美文网首页
iOS推送通知及静默推送相关

iOS推送通知及静默推送相关

作者: Aliv丶Zz | 来源:发表于2019-12-03 13:55 被阅读0次

                                               iOS推送


            在IOS推送服务中,Apple提供了两种不同方式的推送形式,一种是在通知栏上面显示的推送;另一种则是不带消息提醒的推送,俗称“静默消息”。

    1. 普通推送和静默推送的区别

            普通推送:收到推送后(有文字有声音),点开通知,进入APP后,才执行

    - (void)application:(UIApplication didReceiveRemoteNotification:(NSDictionary fetchCompletionHandler:(void result))handler *)application *)userInfo (^)(UIBackgroundFetchResult

            静默推送:(Silent Push)并不是必须要“静默”(通常是没有文字没有声音),只要推送payload中aps字典里包含了"content-available": 1的键值对,都具有静默推送的特性,不用点开通知,不用打开APP,就能执行

    -(void)application:(UIApplication )application)userInfo didReceiveRemoteNotification:(NSDictionary fetchCompletionHandler:(void (^)(UIBackgroundFetchResultresult))handler

    用户完全感觉不到所以静默推送又被我们称做 Background Remote Notification(后台远程推送)。

            静默推送是在iOS7之后推出的一种推送方式。它与其他推送的区别在于允许应用收到通知后在后台(background)状态下运行一段代码,可用于从服务器获取内容更新。

    PS:注册消息通知时通常的弹窗询问权限有什么用呢?其实只是请求用户允许在推送通知到来时能够有alert, badge和sound,而并不是在请求注册推送本身的权限。静默推送即使用户不允许应用的推送,静默推送依然会送达用户设备,只是不会有alert, badge和sound。这也符合静默推送的正常使用场景。


    2. 远程推送时 , 应用的几种状态及对应回调方法

         (1) . 应用开启时 , 应用在前台

         (2) . 应用开启时 , 应用在后台

         (3) . 应用未启动(应用被杀死)

    从苹果APNS服务器远程推送时:

    不使用<UserNotifications/UserNotifications.h>时(iOS10以后可用)

    1 . 如果应用处于 (1) 状态 , 则不会发出声音 , 会直接调用appDelegate的代理方法didReceiveRemoteNotification(didReceiveRemoteNotification:fetchCompletionHandler:)

    2 . 如果应用处于 (2) 状态 , 则会发出提示音, 点击推送消息 , 则会调用appDelegate的代理方法didReceiveRemoteNotification

    3 . 如果应用处于 (3) 状态,则会发出提示音 , 点击推送消息 , 则会开启应用 , 在下面这个方法中会带上launchOptions这个参数,如果实现了application:didReceiveRemoteNotification:fetchCompletionHandler:这个方法,则还会调用这个方法

    注:didReceiveRemoteNotification指以下两个方法。两个方法互斥。在两方法都实现的情况下方法2优先级高

    1. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo

    2. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler

    iOS10使用<UserNotifications/UserNotifications.h>时

    1 . 如果应用处于 (1) 状态 , 会发出声音 , 会直接调用appDelegate的代理方法userNotificationCenter:willPresentNotification:withCompletionHandler

    2 . 如果应用处于 (2) 状态 , 则会发出提示音, 点击推送消息 , 则会调用appDelegate的代理方法

    userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler

    3 . 如果应用处于 (3) 状态,则会发出提示音 , 点击推送消息 , 则会开启应用 , 在下面这个方法中会带上launchOptions这个参数,如果实现了userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler这个方法,则还会调用这个方法


    2. 静默推送及app的状态切换

            在大多数情况下,启动一个app后都是进入前台,比如我们点击应用图标或点推送通知来启动应用。其实app在某些后台事件和特定条件下是可以直接启动到后台(launch into the background)的。

        2.1 应用状态之一Suspended

            这种状态其实和Background类似,而且从用户角度讲应用现在看起来确实是在“后台”,但它和Background状态不同的是Suspended下已经不能执行代码了。应用何时会进Suspended就是玄学了,这是由iOS系统自动控制的,而且不会有任何回调,可以看到UIApplicationDelegate里并没有像applicationWillBecomeSuspended:这种东西。这种状态下的应用虽然还在内存中,但是一旦设备内存吃尽,比如开了炉石传说的游戏,那么系统就会优先干掉(文档上用的是purge这个词)处于Suspended状态的应用,而且也不会有回调。

        2.2 应用启动到前台的生命周期(以点击应用图标开始)

        AppDelegate中走的回调方法 

            · application:willFinishLaunchingWithOptions:

            · application:didFinishLaunchingWithOptions:

            · applicationDidBecomeActive:

        静默推送可以使应用启动到后台

            前提是应用先被退到后台,过一段时间被系统移入Suspended状态,然后又被系统在内存吃紧时回收了内存(相当于应用已经被系统正当杀掉,而非用户双击Home键杀掉),在这以后,该应用收到静默推送即会启动应用到后台。

        AppDelegate中走的回调方法变为

            · application:willFinishLaunchingWithOptions:

            · application:didFinishLaunchingWithOptions:

            · applicationDidEnterBackground:

            这个过程中,系统不会显示应用的window,就是说我们不会看到手机屏幕上突然鬼畜一下应用启动,但是应用的第一屏会被加载和渲染,比如你的window.rootViewController是一个TabBarController,那么它及其默认选中的selectedViewController都会被加载和渲染。这是因为系统认为在后台执行完任务后可能会有UI上的更新,所以在applicationDidEnterBackground:方法执行结束后便会有个快速的截图,来更新用户双击Home时看到的那个应用截图。

    3. 收到静默推送时的后续该如何处理。

            application:didReceiveRemoteNotification:fetchCompletionHandler:

            这是应用收到静默推送的回调方法,我们最多有30s的时间来处理数据,比如静默推送表示某个列表或资源有更新,你可以在此处下载数据,在下载处理完数据后需要尽快调用completionHandler(...)告诉系统处理完毕。

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

        [Downloader fetchData:^(id x){        // 处理数据,更新UI 等

            completionHandler(UIBackgroundFetchResultNewData);

        }];

    }

            如果这次是启动到后台的情况,调用completionHandler(...)后会使应用马上进入之前的状态。那就有可能遇到这样的问题:很多时候我们需要在启动时发送一堆业务上的API请求,如果这次静默推送没有数据需要下载和处理,就会刚把启动处的API请求发出,就调用了completionHandler(...),导致发出的这些请求在下次打开应用时显示超时。这种情况下我们可以强行延时下completionHandler(...)的调用,来保证能在这次收到那些API的返回。

       dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            completionHandler(UIBackgroundFetchResultNoData);

        });

    4. 静默推送


    应用想收到静默推送需要满足的条件:

    1.应用在前台/后台 (应用被杀死就收不到了)

    2.应用实现了

    application:didReceiveRemoteNotification:fetchCompletionHandler:/application:didReceiveRemoteNotification:

    3. 消息定义时需设置:"content-available" = 1

    流程:

      1. 移动端注册消息,向APNs服务器获取deviceToken,并提交给后台保存;

      2. 后台定义消息,并推送给APNs服务器。APNs根据deviceToken做分发。

      3. 移动端收到推送消息后的逻辑处理。

    消息定义示例:

    特殊说明:

    1. APNS去掉alert、badge、sound字段实现静默推送,增加增加字段"content-available":1,也可以在后台做一些事情。

    //静默推送消息格式

    {

    "aps":{

    "alert":"",

    "content-available":1

    },

    "userInfo":"test"

    }

    */

    小结:

    1.应用在后台/前台/被杀死,都可以收到普通的远程推送

    2.应用在后台/前台时,可以通过静默推送,修改一些数据

    3.应用被杀死时(相当于应用已经被系统正当杀掉,而非用户双击Home键杀掉),可以通过Background Fetch短时间唤醒应用

    参考资料:

    http://www.cocoachina.com/articles/23672

    https://www.jianshu.com/p/f326987c737e

    https://www.jb51.net/article/145654.htm

    https://blog.csdn.net/ws_752958369/article/details/79732961

    相关文章

      网友评论

          本文标题:iOS推送通知及静默推送相关

          本文链接:https://www.haomeiwen.com/subject/vjycgctx.html