ANPS
轉自:http://mobiforge.com/developing/story/programming-apple-push-notification-services
http://blog.csdn.net/xinx001/article/details/7445780
本地通知:http://wangjun.easymorse.com/?p=1482
基本概念:
UDID:iPhone 的程序都需要通過 App Store 下載,當某位開發者尚未發布他的程序,又想讓你使用測試版。那你只需要將自己機器的 UDID 提供給開發者,由開發者將此UDID 在 Apple 注冊,他就可以通過Ad-Hoc的方式直接將測試版程序發送給你,由你安裝使用。而這個匹配了 UDID 的程序,也僅僅只能在你的 iPhone 上使用。
application ID(bundle identifier):用來區分app
device tokens:app在注冊時候,會有一項問你是否需要apn通知,有的話,apns會返回device tokens給這個應用,device tokens相當于接收推送通知的地址。然后app會把device tokens發送給后臺服務器。
在自己的mac電腦上制作自己的私鑰密匙,也就是證書申請文件(CSR),你導出這個在鑰匙串中的csr文件,就是以xxx.p12命名的私鑰文件,
然后把這個CSR文件提交給蘋果會生成一個名稱為xxx.cer的SSL證書。生成證書之后的下一步是生成配置文件給xcode用
把證書和私鑰合成為PEM文件。
基本框架
要讓×××送通知服務正常工作,涉及很多方面,下圖是一個基本框架:
應用啟用推送通知功能,需要用戶確認;
應用收到設備識別ID(device token),相當于接收推送通知的地址;
應用將設備識別ID發送到你開發的服務器;
當有推送通知的需要時,你就可以通過你開發的服務組件發送信息到蘋果的服務器上;
×××送通知服務將信息推送到用戶的設備上。
用戶設備接收到推送信息時,顯示提示信息或播放提示音或更新主屏圖標的提示數字,用戶可以從提示信息窗口打開應用程序,應用可以根據提示信息的內容作進一步的處理。
iOS4支持本地通知和后臺多任務,是否我們就不需要推送通知了呢?
答案是否定的,本地通知僅限于周期性定時事件處理,后臺多任務也僅限于一些必須保持運行的應用,比如IP語音、后臺音樂播放、導航等,如果你需要在你的應用關閉時提醒你的用戶,你就必須使用推送通知服務
接下來,我們來探討一些實現×××送通知服務的技術細節,內容比較多,泡好一杯咖啡,安靜認真地閱讀本教程吧。
×××送通知服務的目的
在你的應用中增加×××送通知服務有以下幾項準備工作:
一臺iPhone或iPad,×××送通知服務不能在模擬器上工作,你必須在真機上測試;
你得有付費開通的iOS 開發者會員資格,你必須在蘋果開發者門戶(iOS Provisioning Portal)新增一個新的應用ID、對應的配置文件(provisioning profile)、專屬于的SLL認證證書;在整個過程中,你將創建自己的配置文件和證書,獲取認證證書是很慎重的過程,必須按照規定執行,后文中有詳細 的操作步驟;
一臺聯入互聯網的服務器,×××送通知服務是在互聯網上工作,開發時你可以在你的工作站上測試,但是實際使用時,你至少需要一臺虛擬個人服務器, 但是要保證可以安裝證書,并開放相應的端口與蘋果的服務器建立安全套接字(TLS)網絡連接,一般IDC虛擬空間提供商不會提供此類額外服務,請先與你的 供應商確認這些細節;
當然,還有專門提供×××送通知服務的網絡服務商,你可以自行谷歌之,本文不討論。
推送通知格式
你的服務器組件將根據事件或需要創建推送通知,你得先了解推送通知的具體格式;
一個推送通知包括設備識別ID,通知主體和一些標識字節,通知主體是我們要發送的內容。
首先我們得按JSON格式組織好通知主體,下面是一個最簡單的示例:
{"aps":{"alert":"測試信息","sound":"default"}}
用大括號{}將鍵值對(字典對象)封裝起來,有點像NSDictionary。
通知主體至少得包括一個項目:”aps”,這個項的內容還是一個字典對象,在上面這個示例中,”aps”包括兩個字段:alert和sound,讓設備收到這個推送通知時,設備會彈出一個提示窗口,內容是測試信息,同時播放標準的提示聲音。
在aps這個字段下我們還可以自定義一些內容:
{"aps":{"alert":{"action-loc-key":"Open","body":"Hello, world!"},"badge":2}}
在這個示例中,字段”alert”也變成一個字典對象,字段”action-loc-key”重新定義彈出提示窗口中確認按鈕上的文字,”badge”字段是需要在主屏圖標上顯示的提示數字,這個示例沒有播放聲音。
還有很多通知主體內容的設置方式,你可以改變播放的聲音,可以根據本地語言化的調置提供本地化的提示文字,甚至于加上你自定義的字段內容。更多資料請移至官方《本地和推送通知開發指引(英)》。
出于效率的考慮,推送通知的字節長度不能超過256個字節,類似于短信或推特(微博),所以在組織JSON通知主體內容時,一般我們都不保留換行和空格:
{"aps":{"alert":"Hello, world!","sound":"default"}}
這樣已經很清楚了,不是嗎,超過256個字節的推送通知,蘋果的服務器可是會自動過濾掉的。
正式開始
推送通知不保證發送接收的可靠性!!??
是的,就算APNS接收發送的請求,推送通知的接收也是沒有保證的。
認真考慮你的應用是否適用推送通知,現在沒有辦法確認推送通知發送的狀態和接收與否,發送時間也無法得到保證,可能幾秒也可以半小時。
而且,如果用戶設備通過受限的局域網在線或處于關機狀態,也是收不到推送通知的。
APNS會嘗試在設備重新上線時發送最后一條推送通知,但是這種嘗試不會持續太長時間,之后推送通知就永遠失效了。
別指望在APNS里查找歷史記錄
發送推送通知的成本可能比你估計的要高!增加這個功能很簡單,但是要維護一個比較大的用戶群或一些特殊應用場合時,你可能需要承擔較高的成本。
只要監控你網站上的更新,并發送通知到你的用戶是比較簡單的,但是如果你提供的功能包括自定義監控其他網站的更新時,你的服務器要能夠運行得了可能遠超過你估計的監控任務。
所以你還必須從維護成本上考慮你的應用是否需要這功能。
好了,理論性的東西就這么多了,現在是時候來實踐一下了。在編寫代碼之前,你還需要在蘋果的開發者門戶網站上處理一些煩人的步驟。
配置文件和證書
我勒個去!
APNS需要認證證書!
要在你的應用中啟用推送功能,一個對應的配置文件是必不可少的,你需要用它來跟APNS確認APP,不是嗎?
配置文件和證書只能通過對應有效的蘋果開發者計劃成員來取得,這樣才能保證只有你的服務組件才能發推送通知到你的應用。
如果你有過開發經驗,你知道應用配置文件分為開發和發布兩種類型,推送配置文件也有兩種:
開發(Development).對應著你開發測試時用的應用配置文件
發布(Production).對應著你正式發布時用的應用配置文件
在本教程中,我們只要關注開發配置文件即可。
準備證書申請文件(Certificate Signing Request )
還記得初次通過蘋果開發者門戶獲取開發證書的過程嗎?下面的過程你應該會覺得比較熟悉。但是還是要認真地瀏覽其中的細節,大多數故障問題都跟證書有關。
數字證書基于公私鑰加密方式,這里我們并不需要了解加密的過程,你只要了解數字證書總是和個人私鑰文件合并使用就行了。證書是公鑰的部分,用于建立基于SSL的加密網絡連接,并不需要高強度的保密,而私鑰不同,這是“私的”,你需要好好地保存。
要申請數字認證,你需要先準備一個證書申請文件(CSR),準備好后會在“鑰匙串”程序(MAC OS)中生成一個新的私鑰項目,把證書申請文件發給證書發放方(這里是蘋果開發者門戶),你將可以獲取一個對應的SSL證書。
在你的MAC電腦上的【應用程序/實用工具】下打開“鑰匙串訪問”程序(Applications/Utilities/Keychain Access),在【Keychain Access/Certificate Assistant】菜單中選擇【Request a Certificate from a Certificate Authority….】
如果你沒有找到這個菜單項或是提示“Request a Certificate from a Certificate Authority with key”,你還需要額外在開發者門戶里下載并安裝 WWDR Intermediate Certificate 。
確認沒有選中窗口列表中的任何私鑰,你應該可以看到以下窗口:
輸入你的郵件地址,雖然有人建議說最好是跟開發資格的用戶一致,但是看起來不一樣也沒有關系。
輸入PushChat(示例應用名稱)在common name 項,實際上隨便你填什么,只要你到時能夠通過命名找到你的私鑰就行。
選擇【保存在本地磁盤(Saved to disk)】,將CSR保存為“PushChat.certSigningRequest”。
現在你在“鑰匙串訪問”程序中Keys分類下應該可以找到一個新的私鑰項目,右擊并選擇Export。
將私鑰保存為文件,保存時會提示你輸入口令,命名為“PushChatKey.p12”。
為了方便在本教程里引用,我使用“pushchat” 作為口令,實際應用時應該使用高強度的密碼口令。可不能忘記口令,否則后面你可能無法訪問私鑰文件。
準備應用ID(App ID)和SSL證書
登入蘋果開發者門戶。
首先,我們先填寫一個新的應用ID,每個推送通知服務都對應著唯一的應用,在這里,你不能使用通配符。
在左項菜單中選擇APP IDs,點擊按鈕【New App ID】。
填寫如下:
Description: PushChat
Bundle Seed ID: Generate New (this is the default option)
Bundle Identifier: com.hollance.PushChat
這里你得填上自己的標識:com.yoursite.PushChat,因為你在XCODE得用同樣的標識開發應用。
稍等一會,你就可以生成對應這個APP的SSL證書,你的服務組件通過這個證書也只能發送通知到這個APP。
填寫完畢,你應該可以看到下列信息:
在【Apple Push Notification service】列,有兩行有橙色小圓點起始的信息:【Configurable for Development】 和【Configurable for Production】。 這就意味著這個應用ID已經準備好了,接下來設置相關的選項。點擊【Configure】鏈接。
點選【Enable for Apple Push Notification service】框,點擊對應【Development Push SSL Certificate】的設置按鈕 【Configure】,彈出 ×××送服務SSL證書助理(Apple Push Notification service SSL Certificate Assistant)窗口 :
首先提示你準備好證書簽名申請文件,我們上面已經準備好了,點擊繼續,在下一步中進行上傳CSR文件的操作,選中之前生成的CSR文件然后點擊生成(Generate)。
生成證書需要幾秒鐘,接著點繼續按鈕(Continue)。
下載生成的證書并保存為“aps_developer_identity.cer”。點擊完成按鈕(Done)關閉助理窗口返回APP ID界面。
你可以看到,我們已經激活開發用的證書認證,如果需要你可以在這里重新下載證書,開發證書的有效期為3個月。
等你要正式發布你的應用的時候,你必須在開發認證那一項目下把這個過程重新來一遍。
備注:開發認證的證書有效期為一年,你必須在到期前重新生成一次來保證你的系統正常運行。
在本例中你不需要安裝這個證書,如果你雙擊文件進行了安裝,你可以在鑰匙串訪問程序中查找到,這個證書已經和私鑰綁定在一起了。
制作PEM文件
現在我們有三個文件:
認證簽名申請文件(CSR)
私鑰文件(PushChatKey.p12)
SSL證書文件(aps_developer_identity.cer)
妥善地保存好這三個文件,特別是CSR文件,在你的證書失效之后,你可能會再次用到它來申請證書。原來的私鑰還可以用,只有SSL證書文件是新的。
我們需要轉換證書和私鑰文件為一種常用格式,示例中我們使用PHP開發服務組件,我們需要把證書和私鑰文件合并為PEM格式文件。
我們不用關心是哪一種具體的PEM編碼格式(實際上我也不是很清楚),關鍵是PHP可以用來與服務器建立有效的網絡連接,其他的編程語言可能會用到其它格式的文件。
在這里,我們用MAC電腦的命令行工具OpenSSL來操作,打開一個“終端”(Terminal)程序:
通過cd命令轉到存放三個文件的文件夾,我這里的操作是:
$ cd /Users/matthijs/Desktop
轉換證書 .cer 文件到 .pem 文件格式:
$ openssl x509 -in aps_developer_identity.cer -inform der -outPushChatCert.pem
轉換私鑰 .p12 文件 到 .pem 文件格式:
$ openssl pkcs12 -nocerts -outPushChatKey.pem -inPushChatKey.p12
EnterImportPassword:
MAC verified OK
Enter PEM pass phrase:Verifying-Enter PEM pass phrase:
在這里,你首先要輸入私鑰文件的口令以便訪問.p12文件,接著要求輸入一次新的口令來加密新的PEM文件,這里我們都用“pushchat” ,你也可以使用更復雜的口令來保護你的私鑰。
備注:如果你不輸入一個6位以上的加密口令,openssl工具將給出錯誤信息并取消操作。
最后,我們把這兩個文件合并成一個 .pem 文件:
$ cat PushChatCert.pem PushChatKey.pem > ck.pem
想測試一下證書是否正常,來試一下:
$ telnet gateway.sandbox.push.apple.com 2195Trying17.172.232.226...Connected to gateway.sandbox.push-apple.com.akadns.net.Escape character is'^]'.
這里是生成一個普通的網絡連接,如果有上面的信息,說明你的電腦可以聯上APNS服務器,按Ctrl+C關閉連接。
如果有問題,你需要檢查一下網絡和防火墻的端口2195的設置。
這次我們試一試用私鑰和證書進行SSL加密連接:
$ openssl s_client -connect gateway.sandbox.push.apple.com:2195-cert PushChatCert.pem -key PushChatKey.pem
Enterpass phrase forPushChatKey.pem:
你應該可以看到接下來的整個輸出,我們已經站在正確的起跑線上了。
如果連接成功,你可以輸入幾個字符,當你按下回車,連接就斷開了,連接失敗的話也會有提示信息。
特別提示你有兩個不用的APNS服務器,一個用于測試的沙盒服務器,一個用于正式使用的服務器,我們制作的證書是用于測試的,所以上面的示例中我們使用的是沙盒服務器的地址。
準備配置文件
開發者門戶上的操作還沒有完,點擊左項菜單上的【Provisioning】,點擊【New Profile】新建一個配置文件。
填入如下內容:
配置名稱Profile Name: PushChat Development
證書(Certificates):選中你的開發者證書
應用ID(App ID): PushChat
設備(Devices): 選中你的開發設備
這里的操作跟你之前的沒有什么不用,只是具備推送功能的應用需要一個新配置文件來跟設置好的APP對應起來。
點擊發送按鈕(Submit),新的配置文件就會重新生成,稍等片刻,再刷新頁面即可下載新的配置文件(PushChat_Development.mobileprovision)。
將配置文件下載并加載到XCode(雙擊或拖到XCode圖標上)。
準備正式發布前,你也要這樣操作來準備用發布用的配置文件。
簡單的示例應用
你還在嗎?經歷了這么多終于可以來點興奮點的事情了,不過上面的這些過程是必不可少的,至少這些也不需要天天搞的,否則是會死人的,不是嗎?
我們已經實現與沙盒服務器的加密網絡連接,現在就讓我們來實現推送通知的發送吧。
打開你的XCode,選擇【File】【New Project】,選擇【View-based Application】點擊繼續:
填入以下內容:
Product Name: PushChat
Company Identifier: com.hollance
Device Family: iPhone
根據你的實際情況填入應用名稱和開發者標識,這里我們就填入“com.hollance.PushChat”。你應該填入跟你在開發者門戶里填入的一致信息(com.yourname.PushChat)。
完成新建項目的操作,打開PushChatAppDelegate.m,修改 didFinishLaunchingWithOptions 過程:
-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{self.window.rootViewController =self.viewController;[self.window makeKeyAndVisible];// 通知設備需要接收推送通知 Let the device know we want to receive push notifications[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert)];return YES;}
調用registerForRemoteNotificationTypes 通知系統應用是需要接收推送信息的。
在你的設備上編譯運行應用,模擬器是不支持推送信息的。XCode應該會自動選擇配置文件,如果出現簽名錯誤,你需要在 Code Signing build settings手動選擇之前下載的配置文件。應用啟動時會注冊推送通知服務,彈出下面的確認窗口提示用戶允許此應用接收推送通知服務。
應用只會提示詢問一次,如果用戶選擇接受,設備就一切就緒了。如果用戶選擇了拒絕,應用將永遠無法接收到信息,用戶可以在設備的設置項目中修改此項設定。
應用的名稱將會添加到設置程序中的通知項目下,用戶可以方便地在這里開啟或關閉或自定義接收信息的種類和方式。
應用也可以通過程序來激活具體的提示方式:
UIRemoteNotificationType enabledTypes =[[UIApplication sharedApplication] enabledRemoteNotificationTypes];
還有額外的一件事,為了發送信息到指定的手機,我們還需要一些操作:
-(void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{NSLog(@"我的設備ID: %@", deviceToken);}-(void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{NSLog(@"注冊失敗,無法獲取設備ID, 具體錯誤: %@", error);}
當應用注冊推送服務成功時,就可以獲取用戶設備識別ID(Token ID),這是對應你的設備一個32位的唯一編碼,你可以理解為推送信息的地址。
運行應用,在XCode的終端窗口你可以看到以下信息:
我的設備ID:<740f4707 bebcf74f 9b7c25d4 8e335894 5f6aa01d a5ddb387 462c7eaf 61bb78ad>
設備識別ID(Token ID)是加密的數據結構,儲備在NSData對象中。這里你知道它是32位長度就夠了,上面你看到的是64個16進制的字符,我們將使用這個格式,當然<>和空格要過濾掉。
在模擬器中運行,didFailToRegisterForRemoteNotificationsWithError會返回錯誤:method will be called as push notifications are not supported in the simulator.
應用準備好了,就差最后一件事了。
發送我們的推送通知
之前我們都談到要有服務器或服務組件來實現推送通知的發送和管理,在這里,我們先不急著搭建服務器,這里有一個簡單的PHP腳本用來建立到APNS的連接和發送測試信息到之前的設備上。
你可以在MAC上直接使用:
下載SimplePush源代碼 解開后,修改simplepush.php中的以下幾個地方:
// Put your device token here (without spaces):
$deviceToken ='0f744707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bbad78';// Put your private key's passphrase here:
$passphrase ='pushchat';// Put your alert message here:
$message ='My first push notification!';
復制設備識別ID到變量$deviceToken,別留下任何一個空格,完完全全就是64個16進制字符;指定私鑰的口令和要發送的信息內容;復制ck.pem到腳本所在文件夾,ck.pem包括了證書和私鑰。
開啟終端程序( Terminal):
$ php simplepush.php
如果一切OK的話,腳本將返回:
Connected to APNS
Message successfully delivered
幾秒鐘內,你應該可以在設備上收到推送的信息了。
注意如果應用在開啟運行狀態的話,你看不到任何信息,信息被直接發送給應用本身,但是我們還沒有通過編程來處理收到的信息,不信你可以再試一下。
如果PHP腳本退出并返回錯誤信息,請檢查PEM文件是否正確、連接沙盒服務器是否正常。
PHP腳本具體的實現過程就不討論了,有興趣的或需要自行搭建服務器來管理發送推送通知的可以看此教程的下篇(請找原出處)。
接下來呢
現在你已經成功地實現了應用的推送通知服務,在此教程的下篇中,我們來開發一個簡單的短消息應用(PushChat)來實現用戶之間的推送通知功能。還有完整用于在后臺不間斷提供推送通知服務的服務組件API。
下面是蘋果的官方文檔
RemoteNotificationsPG.pdf (2.5 MB)
本文轉載自:http://guafei.iteye.com/blog/1808445
轉載于:https://blog.51cto.com/5576677/1633606
總結
- 上一篇: word2010多级列表编号变成黑块的解
- 下一篇: PHP资源列表