首先简单介绍一下iOS下推送通知吧!,推送通知分为有local
本地推送,remote
远程推送,而iOS7之后对远程推送进行了扩展,添加了一个silent
静默推送。顾名思义就是偷偷的推你一把😏,而你还不知道发生什么事儿!
local
本地推送
本章节不打算详解本地推送,因为你爱怎么推就怎么推,与外界基本没有任何关系,也不需要用到APNs(英文全称:Apple Push Notification service)、token、证书,这些都是什么鬼👻?自行谷歌百度,So,do yourself!需要了解推送的朋友可以看一下这篇文章打基础:https://my.oschina.net/u/1418722/blog/317422
remote
远程推送
通过编写服务器端代码,发送一条消息来通知Apple苹果公司服务器APNs,然后根据你的设备唯一识别码deviceToken,对你进行推送一条消息,deviceToken怎么来的呀!通过注册通知方法,会调用下面的方法
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
//发送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
当程序处于杀死状态下,再次invoke
唤起程序,可以通过这个字典launchOptions
来获取你未处理消息,这个UIApplicationLaunchOptionsRemoteNotificationKey
key值获取未读通知。当然啦,前提你要点击你的推送通知来invoke
唤起你的程序,要不然只是点击应用图标的话,你还是什么都获取不到,就是这么任性!
NSDictionary *remoteUserInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
Methdo 2 方法2
当应用处于前台状态的时候,会触发这个方法,来获取你的远程推送,但这个方法仅限于应用在前台,而且在iOS 10之后已经不建议使用了,但如果你还要兼容iOS 7以下的推送环境的话...,请继续使用- -!
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在后台处理一些事情,例如上传下载,感兴趣的朋友可以了解一下,静默推送就是基于这个来触发这个方法的
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
//应用在前台,接收远程推送,会进入这个状态
}
else if (state == UIApplicationStateInactive) {
//应用在后台,通过点击远程推送通知,进入这个状态
}
else if (state == UIApplicationStateBackground) {
//应用在后台,收到静默推送,进入这个状态
}
//记得加上这句话,要不然应用在后台时不触发方法3。
completionHandler(UIBackgroundFetchResultNewData);
}
在Background Modes
里面有个Background fetch
的东西,就是上文所说的,当然我们这里勾选Remote notifications
就可以了。那怎么可以触发方法3里面后台状态呢?在服务端加上这个值就可以了"content-available" : 1;
远程推送负载payload
,推送也是有限制的,通过阅读 http://www.jianshu.com/p/4b947569a548 这篇深度好文,大家就会对payload
有更好的理解,对推送这方面也是很不错的。
Tips:当接收到静默推送,用户界面是不会有任何提示的,所以,你懂的
{
"aps" : {
"content-available" : 1;
},
}
那么程序在杀死状态下,这个方法是否会执行呢?答案就是:不会!基本上程序在杀死状态下就是死了,死了还会动,岂不诈尸了。不过这个说法还是不够严谨的。但是我们还是会收到推送的,只不过程序不会作出任何回应!那么我们怎么激活这个方法呢?使用魔法卡死者苏生
😁,好了好了,不开玩笑了!此时只能点击推送通知invoke
唤起程序,那么这时候就会先走方法1
,然后走方法3
的Inactive
状态。如果只是点击应用图标的话,也是不会走方法3
的。接下来讲解iOS 10的推送是怎么样的,方法4
方法5
都是iOS 10接收推送的delegate方法,而iOS 10的推送已经变得很不同了,样式也变得非常丰富了。
Method4 方法4
当接收到推送的时候,用户通过点击response
通知,就会触发方法4
,相当于方法3
下的Inactive
状态。
Method5 方法5
iOS 10把远程推送和本地推送都集成到了这个方法,当应用在前台的时候,接收到推送,就会触发这个方法,相当于方法3
下的Active
状态。那么程序在后台呢?没错,此时就会走方法3
的Background
状态了,当然也必须有这个键值对"content-available" : 1;
。
总结
通过上面的一些方法,我们基本掌握了推送触发方法的流程。首先方法1
,苹果是不建议在这里获取推送的消息的,方法2
基本可以无视了,方法3
基本上iOS 7-iOS 10是必须实现的,要不然程序在后台怎么接收到远程推送呢!方法4、方法5
在iOS 10下接收推送的方法。建议大家多阅读官方文档,会有更好的收获。--文章写的烂,希望大家将就看,有很多地方说得还不够严谨、有欠缺、有遗漏,有不正确的地方欢迎讨论!