通知那些事儿(六):更多的注意点

想了解更多iOS 通知

可以去下面repository看看:

PushNotificationEverything

静默推送

填个坑

设置角标

[UIApplication sharedApplication].applicationIconBadgeNumber = 0;

!!!注意:

应用角标特性

1. 假如本地推送和远程推送的消息payload都不带有badge字段,那么不管角标如何设置。
* 点击推送,点击一条消除一条;
* 点击APP,推送不会消除;

2. 如何本地推送或远程推送中含有payload带有badge字段,
* 假如角标设为“当前角标-1”,且不为0,推送点击一条消除一条,点击主应用,通知中心推送不改变;
* 假如角标设为0,不管点击推送,还是点击应用,那么推送会全部清除。

iOS 10 点击通知中心通知无法跳转

问题:

发现iOS 10系统上,点击通知中心中通知不能跳转。

原因:

应用代理方法application(_:didReceiveRemoteNotification:fetchCompletionHandler:) 。
在iOS 10.0.0上出现bug,无法被调用。

解决方案:

方案一:未使用静默推送

实现application(_:didReceiveRemoteNotification:)方法;

方案二:使用静默推送

application(:didReceiveRemoteNotification:)
application(
:didReceiveRemoteNotification:fetchCompletionHandler:)
均实现。

当这两个方法并存,iOS 系统API说明如下:

If your delegate implements both methods, the app object calls the application(_:didReceiveRemoteNotification:fetchCompletionHandler:)method.

了解更多:

关于该系统bug的讨论:
https://forums.developer.apple.com/thread/62267
https://forums.developer.apple.com/thread/54332
https://forums.developer.apple.com/thread/54322

关于上述两个方法的API说明:
application(_:didReceiveRemoteNotification:)
application(_:didReceiveRemoteNotification:fetchCompletionHandler:)

测试数据

- (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions (1)

- (void)application:(UIApplication)application didReceiveRemoteNotification:(NSDictionary)userInfo (2)

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

说明:
后台:指的是,应用还在活跃状态;

前台:应用在前台;

杀死:用户手动通过应用切换杀死应用;

点击:指的是通过点击通知中心的。

iOS 10

  • 静默推送

    • (2)(3)均实现

      • 后台:调用(3),点击再调用(2)【正常应该调用(3),此处bug】
      • 前台:调用(3)
      • 杀死:调用(3),调用(1)
    • (2)实现

      • 后台:调用(2),点击再调用(2)
      • 前台:调用(2)
      • 杀死:不调用(2),调用(1)
    • (3)实现

      • 后台:调用(3),点击不调用【正常应该调用(3),此处bug】
      • 前台:调用(3)
        • 杀死:调用(1),不调用(3)
  • 远程推送

    • (2)(3)均实现

      • 后台:点击再调用(2)
      • 前台:调用(3)
      • 杀死:调用(2),调用(1)
    • (2)实现

      • 后台:点击调用(2)
      • 前台:调用(2)
      • 杀死:不调用(2),调用(1)
    • (3)实现

      • 后台:点击不调用【正常应该调用(3),此处bug】
      • 前台:调用(3)
        • 杀死:不调用(3),调用(1)

iOS 9

  • 静默推送

    • (2)(3)均实现

      • 后台:调用(3),点击再调用(3)
      • 前台:调用(3)
      • 杀死:调用(3),调用(1)
    • (2)实现

      • 后台:调用(2),点击再调用(2)
      • 前台:调用(2)
      • 杀死:不调用(2),调用(1)
    • (3)实现

      • 后台:调用(3),点击调用(3)
      • 前台:调用(3)
        • 杀死:调用(3),调用(1)
  • 远程推送

    • (2)(3)均实现

      • 后台:点击再调用(3)
      • 前台:调用(3)
      • 杀死:调用(3),调用(1)
    • (2)实现

      • 后台:点击调用(2)
      • 前台:调用(2)
      • 杀死:不调用(2),调用(1)
    • (3)实现

      • 后台:点击调用(3)
      • 前台:调用(3)
        • 杀死:不调用(3),调用(1)

以上数据总结,正常逻辑:

  • 实现application(:didReceiveRemoteNotification:fetchCompletionHandler:)将完全替代application(:didReceiveRemoteNotification:);
  • 静默推送相对于普通远程推送:
    • 在后台,会调用application(:didReceiveRemoteNotification:fetchCompletionHandler:),若未实现,将会调用application(:didReceiveRemoteNotification:);;
    • 杀死后,若实现了application(:didReceiveRemoteNotification:fetchCompletionHandler:)会先调用application(:didReceiveRemoteNotification:fetchCompletionHandler:)。否则,两者一致。

这里有篇博客How to handle remote notification with background mode enabled