轉自: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。
下面是蘋果的官方文檔php
RemoteNotificationsPG.pdf (2.5 MB)編程
本文轉載自:http://guafei.iteye.com/blog/1808445xcode