iOS push 工做機制能夠用下圖簡要歸納php
Provider
:應用本身的服務器;APNS
:Apple Push Notification Service的簡稱,蘋果的PUSH服務器;push的主要工做流程是:html
上述過程當中,有兩個關鍵步驟須要本身處理的是:1.客戶端獲取deviceToken,並上傳到Provider;2.Provider發送push消息到APNS。這兩個步驟中都須要蘋果的push證書受權,下面就來介紹如何生成push證書,以及Provisioning Profile。java
生成push證書前要先生成開發證書github
生成開發證書的過程不詳細介紹,能夠參考如何聯機調試和發佈程序。只是有一點須要注意的,生成開發證書過程當中須要經過Keychain生成一個CSR文件,默認名爲CertificateSigningRequest.certSigningRequest,這個文件將在生成push證書的時候用到。服務器
建立一個App ID網絡
push_demo
;com.company.appname
這樣的格式,例如com.mycompany.demo
;注意:要用push功能的Bundle Identifier必定不能出現通配符,好比
com.mycompany.*
,這樣的名字是不能使用push的。app
生成Push SSL Certificateiphone
生成好App ID後點擊Configure
進入配置頁。打開Enable for Apple Push Notification service
選項,該選項下有Development Push SSL Certificate
和Production Push SSL Certificate
兩個SSL Certificate能夠配置,前面一個是用來的開發的push證書,後面一個是用來發布的。咱們以開發push證書爲例,點擊Development Push SSL Certificate
->Configure
,後面會要求選擇CSR文件,這就是生成開發證書時的CertificateSigningRequest.certSigningRequest文件,選擇好CSR後就生成好相應的SSL Certificate了。下載下來,保存名爲aps_developer.cer
。ide
從Keychain中導出私鑰、設置好密碼,命名爲private_key.p12
生成push證書
這時咱們一共獲得3個文件:
將aps_developer.cer轉成pem格式
openssl x509 -in aps_developer.cer -inform DER -out aps_developer.pem -outform PEM
將private_key.p12格式的私鑰轉換成private_key.pem
openssl pkcs12 -nocerts -out private_key.pem -in private_key.p12
這一步會要求輸入p12私鑰的密碼,以及設置新生成的pem的密碼。
建立用於服務端的SSL p12格式證書,命名爲aps_developer.p12
openssl pkcs12 -export -in aps_developer.pem -inkey private_key.pem -certfile CertificateSigningRequest.certSigningRequest -name "aps_developer" -out aps_developer.p12
這一步會要求輸入private_key.pem的密碼,注意不是private_key.p12的密碼。若是密碼錯誤,或者CertificateSigningRequest.certSigningRequest文件不匹配都不能正常生成aps_developer.p12文件,若是生成的aps_developer.p12文件大小是0,說明生成過程當中出了問題,請檢查pem私鑰、密碼、以及CertificateSigningRequest.certSigningRequest是否正確。
aps_developer.p12就是Provider向APNS發送push消息須要的SSL證書。把這個證書和密碼提供給服務端,服務端就能夠發送push消息給APNS了。這時服務端已經能夠工做了,但客戶端還必須配置相應的Provisioning Profile才能啓動應用的push功能。
服務器配置需注意的是,因爲咱們生成的是開發環境的push證書,因此服務器應該鏈接APNS的sandbox環境地址:
gateway.sandbox.push.apple.com:2195
,若是應用正式發佈,就要鏈接正式環境,必須生成相應的發佈證書,並鏈接APNS正式環境地址:gateway.push.apple.com:2195
。
生成Provisioning Profile
com.mycompany.demo
。服務端要發送push消息給某一設備還必須知道該設備的deviceToken。應用運行後獲取到deviceToken,而後上傳給服務器,下面介紹應用如何獲取deviceToken。應用必須先註冊使用push功能。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge)]; // do something // ... }
在AppDelegate中添加下面方法來獲取deviceToken:
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *token = [NSString stringWithFormat:@"%@", deviceToken]; NSLog(@"%@", token); } - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"%@", error); }
應用獲取到deviceToken後,上傳給Provider,Provider就能夠用這個deviceToken給這個設備push消息了。
服務器配置好證書並拿到deviceToken後就能夠向APNS發送消息了。發送消息的格式以下圖所示:
Payload就是push的消息負載,這就是應用須要關心的數據。 Payload是一個JSON字典,最大值是 256 字節,超過這個限制,APNS將拒絕轉發。基本格式以下:
{ "aps": { "alert":"Hello Push!", "badge":1, "sound":"default" }, "page":"home" }
必須包含aps
鍵值。badge
表示應用程序圖標顯示的數字,sound
表示收到push的提示音。 Payload的具體結構參考Apple Push Notification Service
要在這個結構中新增自定義數據,請加在aps空間以外。好比後臺推送消息給應用同時要求應用打開某個頁面:
後臺告訴客戶端收到這個push後打開應用的主頁,這裏的page、home都是本身定義的。必須注意的是,Payload大小不能超過限制,因此能夠把自定義數據更簡化點,好比能夠把home與編號1對應,page簡寫爲p,這樣"p":1
表示打開主頁,能夠縮小Payload的大小。
iOS系統收到push消息後,若是用戶點擊查看,系統將根據證書啓動相應應用。若是應用已經啓動,將調用AppDelegate的方法:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { // userInfo 就是push消息的Payload }
若是應用尚未啓動,經過push冷啓動後,仍然能在啓動後獲取Payload:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; NSLog(@"Payload: %@", userInfo); }
目前爲止,push功能基本就完成了,能夠開始push功能測試了,若是服務器還沒開發完成,或者想快速測試是否能正常push,可使用下面的代碼實現後臺push測試。發送push前要配置好SSL證書,以及deviceToken和Payload結構。
還有個小問題,當Payload設置了badge,應用圖標上將一直顯示一個數字提示,若是要清除數字提示,或者設置成其餘數字,調用下面函數就能夠完成。
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:number];
number爲0就會清除數字提示。