如果在应用未收到时推送通知消失 运行

Push notifications disappear if received while app not running

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

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

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

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

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

推送通知似乎消失了,因为当应用程序在后台启动并执行时 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 通知中心,直到用户点击它或启动它手动应用程序。

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

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


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

I found that manually setting the application badge number was causing the notifications to disappear.

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

根据人机界面指南

Keep badges up to date. Update your app’s badge as soon as people view the corresponding information. You don’t want people to think there’s new information available, only to find that they’ve already seen it. Note that reducing a badge’s count to zero removes all related notifications from Notification Center.

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