APNS(Apple Push Notification Service)是蘋果公司提供的消息推送服務(wù)。其原理就是,第三方應(yīng)用將要推送給用戶的信息推送到蘋果服務(wù)器揍障,蘋果服務(wù)器再通過統(tǒng)一的系統(tǒng)接口將這些信息推送到用戶的手機(jī)上。如果對此不舍了解的朋友可以參見這篇文章:一步一步教你做ios 推送
本文著重叫在App端如何處理推送信息。主要涉及一下幾個比較重要的函數(shù)品腹,而這些函數(shù)都是AppDelegate類中:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
?做過iOS 開發(fā)的人對這個函數(shù)都會很熟悉,這是在程序結(jié)束啟動红碑,并即將運(yùn)行時調(diào)用的舞吭,通常一些?初始化的工作可以在這個函數(shù)中處理。同樣的析珊,推送的相關(guān)初始化操作也需要在這個部分完成羡鸥。這一部分的工作主要分為兩部分: 推送類型的注冊:
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound | UIRemoteNotificationAlert];
這行代碼告訴了系統(tǒng),該程序注冊的推送消息類型忠寻,通常包括badge惧浴、聲音以及alert通知。 處理程序沒有啟動時的推送消息: 如果是程序正在運(yùn)行或者說程序正在后臺奕剃,那么這個時候處理推送消息的工作都是在:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
或者:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
中完成衷旅。但是如果用戶點(diǎn)擊推送通知的時候程序還沒有被啟動捐腿,這個時候以上兩個函數(shù)都是接收不到用戶的推送通知的,這個時候需要在
application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*) launchOptions
函數(shù)里面進(jìn)行處理柿顶。而推送消息的相關(guān)信息就存儲在launchOptions這個字典里茄袖。具體參照如下代碼:
NSDictionary* pushInfo = [launchOptions objectForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"];
if (pushInfo)
{
NSDictionary *apsInfo = [pushInfo objectForKey:@"aps"];
if(apsInfo)
{
//your code here
}
}
- (void)application:(UIApplication *)applicationdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
- (void)application:(UIApplication *)applicationdidFailToRegisterForRemoteNotificationsWithError:(NSError *)error
為了讓device端可以接收到推送消息,需要將設(shè)備的token傳送到蘋果的服務(wù)器九串,這個token就相當(dāng)于設(shè)備的識別碼绞佩,每一臺蘋果設(shè)備都有唯一的token,蘋果的服務(wù)器就是通過這個token找到對應(yīng)的設(shè)備猪钮,并傳送相應(yīng)地消息品山。這兩個函數(shù)就是在傳送token成功或者失敗后調(diào)用的,用戶在對應(yīng)的函數(shù)里面做一些相應(yīng)地處理烤低。
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
都是程序在運(yùn)行過程中(無論當(dāng)前程序處于前臺還是后臺)接收到推送消息的處理函數(shù)肘交。根據(jù)蘋果的官方文檔,建議大家使用
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
另外就是-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^ )(UIBackgroundFetchResult))completionHandler
還有一個作用扑馁。根據(jù)蘋果給出的文檔涯呻,系統(tǒng)給出30s的時間對推送的消息進(jìn)行處理,此后就會運(yùn)行CompletionHandler程序塊腻要。
在處理這類推送消息(即程序被啟動后接收到推送消息)的時候复罐,通常會遇到這樣的問題,就是當(dāng)前的推送消息是當(dāng)前程序正在前臺運(yùn)行時接收到的還是說是程序在后臺運(yùn)行雄家,用戶點(diǎn)擊系統(tǒng)消息通知欄對應(yīng)項進(jìn)入程序時而接收到的效诅?這個其實(shí)很簡單,用下面的代碼就可以解決:
void application:(UIApplication*)application didReceiveRemoteNotification:NSDictionary)userInfo fetchCompletionHandler:((^)UIBackgroundFetchResult)completionHandler{
if (application.applicationState == UIApplicationStateActive) {
NSLog(@"執(zhí)行前臺對應(yīng)的操作");
} else if (application.applicationState == UIApplicationStateInactive) {
// 后臺進(jìn)入前臺
NSLog(@"執(zhí)行后臺進(jìn)入前臺對應(yīng)的操作");
}
####其他代碼
}
關(guān)于userInfo的結(jié)構(gòu)趟济,參照蘋果的官方結(jié)構(gòu):
{
"aps" : {
"alert" : "You got your emails.",
"badge" : 9,
"sound" : "bingbong.aiff"
},
"acme1" : "bar",
"acme2" : 42
}
即key aps對應(yīng)了有一個字典乱投,里面是該次推送消息的具體信息。具體跟我們注冊的推送類型有關(guān)顷编。另外剩下的一些key就是用戶自定義的了戚炫。