【问题标题】:Push notifications disappear if received while app not running如果在应用程序未运行时收到推送通知,则会消失
【发布时间】:2016-09-07 13:23:07
【问题描述】:

我正在开发一个可以接收推送通知的应用程序,在某些情况下,它会触发后台获取操作。因此,我为我的应用启用了remote-notification 后台功能。

当应用暂停时,推送通知会导致应用唤醒并执行application:didReceiveRemoteNotification:fetchCompletionHandler,横幅会出现在主屏幕上,并且通知会一直保留在通知中心,直到用户点击它以启动应用。它完全可以正常工作。

当应用程序未运行时,只要应用程序未被用户强制退出(请参阅apple's documentation),应用程序就会启动通知,并且应用程序会执行application:didFinishLaunchingWithOptionsapplication:didReceiveRemoteNotification:fetchCompletionHandler。横幅出现在主屏幕上,但随后通知消失。它不会保留在通知中心。此外,如果设备被锁定,有时通知甚至在发出警报声之前就消失了。

有趣的是,如果我禁用远程通知后台模式,一切正常。在这种情况下,当推送通知到达时应用程序不会启动。

当远程通知后台模式开启并且传入通知启动未运行的应用程序时,如何防止通知消失?我是否需要在application:didFinishLaunchingWithOptions 中包含一些内容,让应用知道它正在后台启动,并且不应丢弃通知?

【问题讨论】:

  • 您是否正确调用了application:didReceiveRemoteNotification:fetchCompletionHandler: 方法中的完成处理程序?
  • 是的,不是这样。我实际上只是想出了问题所在。我会尽快发布答案。基本上,我的application:didFinishLaunchingWithOptions 有一行注册推送与我正在使用的SDK (Kinvey)。我不知道究竟会发生什么,但是当它被调用时,应用程序似乎重新注册推送,并处理传入的推送。所以我写了几行以避免在后台启动应用程序时调用它,并且解决了它。

标签: ios push-notification background-process appdelegate


【解决方案1】:

我发现手动设置应用程序徽章编号导致通知消失。

它不是手动设置徽章编号。它将徽章编号设置为零。

根据人机界面指南

使徽章保持最新。用户查看相应信息后,立即更新您的应用程序徽章。您不希望人们认为有可用的新信息,只是发现他们已经看到了。请注意,将徽章的计数减少为零会从通知中心删除所有相关通知。

https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/notifications/

【讨论】:

    【解决方案2】:

    按照此处接受的答案的建议,如果应用程序在后台,我尝试不注册通知,但它并没有为我解决这个问题。我发现手动设置应用程序徽章编号会导致通知消失。

    我在application:didFinishLaunchingWithOptions: 中有代码检查用户的状态,如果没有活动用户,我会(除其他外)将徽章图标设置为 0,或者将其设置为我保存在 @987654322 中的值@ 如果有活动用户。事实证明,这些行中的任何一条都会导致通知消失并几乎立即停止播放通知声音。在随后的推送中它没有发生的原因是因为didFinishLaunching 很长一段时间没有被再次调用。


    tl;dr - 检查以确保您没有在任何应用生命周期方法或 didReceiveRemoteNotification 中手动设置应用程序徽章图标。如果您的通知仅在第一次收到时消失,请仔细查看didFinishLaunching

    【讨论】:

      【解决方案3】:

      推送通知似乎消失了,因为当应用程序在后台启动并执行 application:didFinishLaunchingWithOptions: 时,它正在重新注册远程通知。重新注册似乎会丢弃所有排队的消息。

      我的解决方案是在调用推送注册方法之前检查应用程序是否由于推送通知而在后台启动。我用的是Kinvey SDK,所以下面的代码使用了Kinvey的方法,但是我强烈怀疑这个方案会适用于其他的推送注册方法,包括标准的UIApplication.registerForRemoteNotifications

      导致我的问题的代码是:

      func application(application: UIApplication,
          didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
      {
          // Initialize Kinvey SDK singleton
          KCSClient.sharedClient().initializeKinveyServiceForAppKey("myappid",
              withAppSecret: "mysecret",
              usingOptions: nil)
      
          KCSPush.registerForPush()
          // rest of method...
      }
      

      我解决了这个问题,把它改成:

      func application(application: UIApplication,
          didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
      {
          // Initialize Kinvey SDK singleton
          KCSClient.sharedClient().initializeKinveyServiceForAppKey("myappid",
              withAppSecret: "mysecret",
              usingOptions: nil)
      
          if let _ = 
              launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {
      
              let appState: UIApplicationState = UIApplication.sharedApplication().applicationState
      
              if appState == .Active || appState == .Inactive {
                  KCSPush.registerForPush()
              }
          } else {
              KCSPush.registerForPush()
          }
          // rest of method...
      }
      

      现在,当应用通过传入的推送通知启动到后台时,它不会重新注册推送,并且通知会保留在 iOS 通知中心,直到用户点击它或手动启动应用。

      【讨论】:

      • 啊,非常感谢你。一直在为此苦苦挣扎?
      猜你喜欢
      • 2019-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多