相比起Android,iOS在推送方面無疑慣例得更好。APNS(Apple Push Notification Service)是蘋果公司提供的消息推送服務。其原理就是,第三方應用將要推送給用戶的信息推送到蘋果服務器,蘋果服務器再通過統一的系統接口將這些信息推送到用戶的手機上。如果對此不捨了解的朋友可以參見這篇文章:一步一步教你做ios 推送
本文著重叫在App端如何處理推送信息。主要涉及一下幾個比較重要的函數,而這些函數都是AppDelegate類中:
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound | UIRemoteNotificationAlert];這行代碼告訴了系統,該程序注冊的推送消息類型,通常包括badge、聲音以及alert通知。 處理程序沒有啟動時的推送消息: 如果是程序正在運行或者說程序正在後台,那麼這個時候處理推送消息的工作都是在:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 或者:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
中完成。但是如果用戶點擊推送通知的時候程序還沒有被啟動,這個時候以上兩個函數都是接收不到用戶的推送通知的,這個時候需要在application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*) launchOptions 函數裡面進行處理。而推送消息的相關信息就存儲在launchOptions這個字典裡。具體參照如下代碼:NSDictionary* pushInfo = [launchOptions objectForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"]; if (pushInfo) { NSDictionary *apsInfo = [pushInfo objectForKey:@"aps"]; if(apsInfo) { //your code here } }
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo和
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
都是程序在運行過程中(無論當前程序處於前台還是後台)接收到推送消息的處理函數。根據蘋果的官方文檔,建議大家使用
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
因為前者在程序處於後台的時候是無法接收到推送信息的(經實測-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo其實可以接收到,不知道是怎麼回事,希望大蝦解疑)。另外就是-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 還有一個作用。根據蘋果給出的文檔,系統給出30s的時間對推送的消息進行處理,此後就會運行CompletionHandler程序塊。
在處理這類推送消息(即程序被啟動後接收到推送消息)的時候,通常會遇到這樣的問題,就是當前的推送消息是當前程序正在前台運行時接收到的還是說是程序在後台運行,用戶點擊系統消息通知欄對應項進入程序時而接收到的?這個其實很簡單,用下面的代碼就可以解決:
void application:(UIApplication*)application didReceiveRemoteNotification:NSDictionary)userInfo fetchCompletionHandler:((^)UIBackgroundFetchResult)completionHandler{ if (application.applicationState == UIApplicationStateActive) { NSLog(@"active"); //程序當前正處於前台 } else if(application.applicationState == UIApplicationStateInactive) { NSLog(@"inactive"); //程序處於後台 } }
{
"aps" : {
"alert" : "You got your emails.",
"badge" : 9,
"sound" : "bingbong.aiff"
},
"acme1" : "bar",
"acme2" : 42
}即key aps對應了有一個字典,裡面是該次推送消息的具體信息。具體跟我們注冊的推送類型有關。另外剩下的一些key就是用戶自定義的了。