iOS之Notification

在項目的AppDelegate中的didFinishLaunchingWithOptions方法中加入下面的代碼:

 

  1. [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge)];   

 

通過registerForRemoteNotificationTypes方法,告訴應用程序,能接受push來的通知。

 

在項目的AppDelegate中添加下面的方法來獲取deviceToken:

 

  1. - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {     
  2.     NSString *token = [NSString stringWithFormat:@"%@", deviceToken];  
  3.     NSLog(@"My token is:%@", token);  
  4. }  
  5.   
  6. - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {      
  7.     NSString *error_str = [NSString stringWithFormat: @"%@", error];  
  8.     NSLog(@"Failed to get token, error:%@", error_str);  
  9. }  

 

獲取到的deviceToken,我們可以提交給後臺應用程序,發送通知的後臺應用程序除了需要知道deviceToken之外,還需要一個與APNS連接的證書。

 

(自iOS開發文檔"Local and Push Notification Programming Guide"裏與iOS相關的部分翻譯)


-----------------------------------------▲客戶端處理------------------------------------------
建議每次程序啓動的時候都調用registerForRemoteNotificationTypes來重新獲取設備相關的token,而不要緩存token.
這是因爲,如果用戶重裝了iOS或者用戶換了設備並且恢復程序備份到一個新的設備,都將導致這個token值不一樣。

當iOS收到遠程消息時,

如果應用程序isn't running in the foreground,iOS會處理這個消息,比如彈出一個框、在應用程序的icon上顯示紅色數字。
然後如果用戶通過點擊彈框進入程序,iOS會啓動程序並調用application:didFinishLaunchingWithOptions並且拿遠程消息的payload進行傳參.
如果用戶直接點擊app icon進入程序,iOS會啓動程序並同樣調用application:didFinishLaunchingWithOptions,但是傳參將不會有遠程消息的任何信息。

如果應用程序is running in the foreground,就會調用application:didReceiveRemoteNotification.

----------------------------------------------▲APNs----------------------------------------------
IOS設備會持久連接APNs以接受遠程消息。

provider發送消息到APNs,然後APNs再發送到目標IOS設備。(這個傳輸是單向的。)
這個消息的內容含兩部分:設備token和payload.

反饋服務--
    有時候APNs發送消息到某設備(token)某程序(bundle identifier)但是該設備並沒有這個程序,多次這種情況之後,APNs會通知provider,通過其連接的一個反饋服務(a feedback service)。
    反饋服務爲每一個程序維護了一個失效設備列表,provider應該獲取這個列表從而停止向APNs發送以這些設備爲目的地的某程序的遠程消息。

APNs的安全架構--
provider需要一個有效證書才能和APNs連接(這個證書有目標程序的Bundle identifier信息)。
與APNs連接後,provider向APNs發送的消息帶有設備token(由目標程序連接provider然後發來token),APNs以此找到目標設備,然後看目標設備裏的目標程序有接受推送的證書,APNs以此驗證給目標設備的目標程序發送的消息是合法的。

注意:遠程消息是不可靠的。

----------------------------------------▲Provider-------------------------------------------
Payload--
最多256bytes。


本地化alert:
eg:"alert" : {"loc-key":"GAME_PLAY_REQUEST_FORMAT","loc-args":["Jenna","Frank"]},
程序包裏面的本地化字符串如下:
"GAME_PLAY_REQUEST_FORMAT" = "%@ and %@ have invited you to play Monopoly";
這樣,最後顯示alert的字符串就是:
"Jenna and Frank have invited you to play Monopoly"

一個JSON Payload的完整例子(爲了性能,建議去掉空白字符)
{
"aps" : 
{
"alert" : "Message received from Bob",
"badge" : 5,
"sound" : "bingbong.aiff"
},
"myCustomData" : ["bang", "bang、bang、bang"],
"myCustomData2": 42
}

----------------------------------------▲部署-------------------------------------------
要部署provider端client/server程序,需要來自蘋果的SSL證書。下稱provider證書。
provider證書對應於特定的iOS Application(Bundle identifier)。
同時,provider證書分爲開發測試和產品兩種版本,對應於兩種APNs環境:
Sandbox(Development) :可用模擬器測試。地址是gateway.sandbox.push.apple.com: TCP 2195
Production(Distribution):gateway.push.apple.com: TCP 2195
同 時,provision profile也對應了兩個版本:Development和Distribution.(The Distribution provision profile is a requirement for submitting your application to the App Store.)

可以在xcode裏看iOS application所處何環境:看編譯選項裏的code-signing identity,如果是"iPhone Developer:Firstname Lastname"證書與provisioning profile匹配成對,說明是sandbox環境。如果是"iPhone Distribution:Companyname"證書與provision profile匹配成對,說明是production環境。根據release和debug分別配置code-signing identity選項的證書將會是一個好主意。

注意:儘管SSL證書(即provider證書)沒有放到iOS application的providion profile裏,但是ios application是否支持遠程消息推送依然取決於profile,因爲profile內含開發者證書、設備ID、application ID(Bundle identifier)、"是否支持推送"(在蘋果開發者網站上配置證書的時候配置的)等信息。(The provisioning profile is a collection of assets that associates developers of an application and their devices with an authorized development team and enables those devices to be used for testing.The profile contains certificates,device identifiers,the application's bundle ID,and all entitlement,including <aps-environment>.)
以文本方式打 開*.mobileprovision,會看到裏面類似xml格式,其中<key>Entitlements</key>裏包含 了<key>aps-environment</key>,說明支持遠程消息推送,<key>aps- environment</key>下面的<string>說明是調試版本還是發佈版本(對應於Sandbox環境和 Production環境)。

●安裝證書到服務端
你應該安裝SSL證書和私匙到你的provider程序運行的服務器上。
步驟如下:
0.安裝該證書到mac電腦的鑰匙串。
1.打開鑰匙串,在左側面板上點擊我的證書欄。
2.找到這個SSL證書,展開會看到證書和私匙。
3.我們選中證書和私匙,然後導出爲"個人信息交換文件"--即擴展名爲p12的文件。
4.provider服務器程序最好用Ruby和Perl這類語言,可以方便的處理"個人信息交換文件"裏的證書。mac下打開終端輸入以下命令以把證書轉換爲這類語言樂於交流的格式:
openssl pkcs12 -in CertificateName.p12 -out CertificateName.pem -nodes
5.把這pem文件拷到服務器上並安裝到某個適當的位置。


----------------------------------------▲Provider與APNs連接----------------------------------------
●連接APNs之前provider需要具備什麼
APNs提供的連接接口是二進制的、streaming TCP socket、異步 的。
Production環境是通過gateway.push.apple.com:2195,Development環境是gateway.sandbox.push.apple.com:2195。
Provider可以建立多個與APNs的連接。每個都得用TLS(or SSL)來建立安全通道,需要用到SSL證書(就是上面提到的provider連接APNs要用到的SSL證書)。
----------------------
Note  要建立與APNs的TLS會話,需要在provider服務器上安裝Entrust Secure CA根證書。Moa OS X是默認已安裝的,其他系統的話,可以沒有安裝,可以從Entrust SSL Certificates的網站http://www.entrust.net/下載安裝根證書。
----------------------

●發送消息的二進制接口和消息的數據包格式
消息須是網絡字節順序(即大尾順序),消息裏面的payload部分不可以超過256字節,且不得以'\0'結尾。

消息格式見"The Binary Interface and Notification Formats"章節。

●The Feedback Service
feedback service包含了這樣的列表:某iOS應用程序對應的"設備"("設備"用二進制格式的設備token來標識)。--這些設備是由於各種原因而不能接收APNs發來的消息。
Provider應該定期查詢這個列表,並且作出對應處理,如:停止向這些的設備發送消息。

provider訪問feedback server通過一個與發送消息類似的二進制接口。
Production環境通過feedback.push.apple.com:2196來建立連接,Development通過feedback.sandbox.push.apple.com:2196。

feedback service和發送消息是不同的服務接口(但都屬於APNs),他的連接方式和發送消息是一樣的。也要通過證書建立SSL連接,連接後你不需要發送任何命令,直接開始讀取流一直讀完爲止,然後provider要解析讀到的數據。

數據是由多個這樣的格式組成的:
| 四字節時間 | 2字節的token 長度 | 32字節的設備token |
關 於"四字節時間":Provider需要判斷對應設備的這個iOS應用程序有沒有在該時間之後重新像provider發送註冊推送消息所獲得的設備 token。如果沒有,就認爲該設備失效了,需停止向該設備發送消息。如果有,那就是這個設備失效過,但是現在又有效了,只是feedback service還沒來得及刷新列表。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章