首先簡單介紹一下iOS下推送通知吧!,推送通知分為有local本地推送,remote遠程推送,而iOS7之后對遠程推送進行了擴展,添加了一個silent靜默推送。顧名思義就是偷偷的推你一把??,而你還不知道發(fā)生什么事兒!
local本地推送
本章節(jié)不打算詳解本地推送,因為你愛怎么推就怎么推,與外界基本沒有任何關系,也不需要用到APNs(英文全稱:Apple Push Notification service)、token、證書,這些都是什么鬼???自行谷歌百度,So,do yourself!需要了解推送的朋友可以看一下這篇文章打基礎:https://my.oschina.net/u/1418722/blog/317422
remote遠程推送
通過編寫服務器端代碼,發(fā)送一條消息來通知Apple蘋果公司服務器APNs,然后根據你的設備唯一識別碼deviceToken,對你進行推送一條消息,deviceToken怎么來的呀!通過注冊通知方法,會調用下面的方法
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
//發(fā)送deviceToken到你的服務器端
NSLog(@"deviceToken:%@", deviceToken);
}
//如果deviceToken獲取不到會進入此事件
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
}
那么大家都知道deviceToken怎么來了吧!接下來才是重點,那么我們收到推送的時候會走那個方法??!還有怎么處理??!來看看有哪些方法,我們來一條一條來分析( ̄▽ ̄*)
(1) - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
(2) - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
(3) - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
(4) - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
(5) - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
Method 1 方法1
當程序處于殺死狀態(tài)下,再次invoke喚起程序,可以通過這個字典launchOptions來獲取你未處理消息,這個UIApplicationLaunchOptionsRemoteNotificationKeykey值獲取未讀通知。當然啦,前提你要點擊你的推送通知來invoke喚起你的程序,要不然只是點擊應用圖標的話,你還是什么都獲取不到,就是這么任性!
NSDictionary *remoteUserInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
Methdo 2 方法2
當應用處于前臺狀態(tài)的時候,會觸發(fā)這個方法,來獲取你的遠程推送,但這個方法僅限于應用在前臺,而且在iOS 10之后已經不建議使用了,但如果你還要兼容iOS 7以下的推送環(huán)境的話...,請繼續(xù)使用- -!
Method 3 方法3
終于要說到全文的重點了,也是現在推送最核心的方法:這個方法- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler跟方法2有什么不同呢?很明顯啦,方法名字都不一樣還不明顯??,不要打我,我們來說正經的。我們可以看到(void (^)(UIBackgroundFetchResult result))這個block里面有一個UIBackgroundFetchResult,看一看里面的枚舉
typedef NS_ENUM(NSUInteger, UIBackgroundFetchResult) {
UIBackgroundFetchResultNewData,
UIBackgroundFetchResultNoData,
UIBackgroundFetchResultFailed
} NS_ENUM_AVAILABLE_IOS(7_0);
大家一看都知道要干啥的,這里就不廢話了,重點要說的是背后引入的這個概念Background fecth,iOS 7之后蘋果引入了這么個東東 多任務處理API--Background Fetch,它允許我們通過這個API在后臺處理一些事情,例如上傳下載,感興趣的朋友可以了解一下,靜默推送就是基于這個來觸發(fā)這個方法的
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
//應用在前臺,接收遠程推送,會進入這個狀態(tài)
}
else if (state == UIApplicationStateInactive) {
//應用在后臺,通過點擊遠程推送通知,進入這個狀態(tài)
}
else if (state == UIApplicationStateBackground) {
//應用在后臺,收到靜默推送,進入這個狀態(tài)
}
//記得加上這句話,要不然應用在后臺時不觸發(fā)方法3。
completionHandler(UIBackgroundFetchResultNewData);
}

在Background Modes里面有個Background fetch的東西,就是上文所說的,當然我們這里勾選Remote notifications就可以了。那怎么可以觸發(fā)方法3里面后臺狀態(tài)呢?在服務端加上這個值就可以了"content-available" : 1;遠程推送負載payload,推送也是有限制的,通過閱讀 http://www.itdecent.cn/p/4b947569a548 這篇深度好文,大家就會對payload有更好的理解,對推送這方面也是很不錯的。
Tips:當接收到靜默推送,用戶界面是不會有任何提示的,所以,你懂的
{
"aps" : {
"content-available" : 1;
},
}
那么程序在殺死狀態(tài)下,這個方法是否會執(zhí)行呢?答案就是:不會!基本上程序在殺死狀態(tài)下就是死了,死了還會動,豈不詐尸了。不過這個說法還是不夠嚴謹的。但是我們還是會收到推送的,只不過程序不會作出任何回應!那么我們怎么激活這個方法呢?使用魔法卡死者蘇生??,好了好了,不開玩笑了!此時只能點擊推送通知invoke喚起程序,那么這時候就會先走方法1,然后走方法3的Inactive狀態(tài)。如果只是點擊應用圖標的話,也是不會走方法3的。接下來講解iOS 10的推送是怎么樣的,方法4 方法5都是iOS 10接收推送的delegate方法,而iOS 10的推送已經變得很不同了,樣式也變得非常豐富了。
Method4 方法4
當接收到推送的時候,用戶通過點擊response通知,就會觸發(fā)方法4,相當于方法3下的Inactive狀態(tài)。
Method5 方法5
iOS 10把遠程推送和本地推送都集成到了這個方法,當應用在前臺的時候,接收到推送,就會觸發(fā)這個方法,相當于方法3下的Active狀態(tài)。那么程序在后臺呢?沒錯,此時就會走方法3的Background狀態(tài)了,當然也必須有這個鍵值對"content-available" : 1;。
總結
通過上面的一些方法,我們基本掌握了推送觸發(fā)方法的流程。首先方法1,蘋果是不建議在這里獲取推送的消息的,方法2基本可以無視了,方法3基本上iOS 7-iOS 10是必須實現的,要不然程序在后臺怎么接收到遠程推送呢!方法4、方法5在iOS 10下接收推送的方法。建議大家多閱讀官方文檔,會有更好的收獲。--文章寫的爛,希望大家將就看,有很多地方說得還不夠嚴謹、有欠缺、有遺漏,有不正確的地方歡迎討論!