为什么userNotificationCenter didReceive没有被触发?

时间:2018-11-24 16:44:18

标签: ios swift push-notification unusernotificationcenter

这是我的代码的一部分。我想使用UNUserNotificationCenterUNUserNotificationCenterDelegate处理通知事件。

当应用程序处于前台状态时,此代码捕获通知事件。但是"didReceive"不会被触发为背景状态。

func application(_ application: UIApplication,
                         didFinishLaunchingWithOptions launchOptions:
            [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
            UNUserNotificationCenter.current().delegate = self
    application.registerForRemoteNotifications()
    return true
    }    
        func userNotificationCenter(_ center: UNUserNotificationCenter,
                                    willPresent notification: UNNotification,
                                    withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
        {
            print("willPresent") /// This works
            completionHandler([.alert, .badge, .sound])
        }
        func userNotificationCenter(_ center: UNUserNotificationCenter,
                                    didReceive response: UNNotificationResponse,
                                    withCompletionHandler completionHandler: @escaping () -> Void) {
            print("didReceive") /// This doesn't work
            completionHandler()
        }

但是,如果我不使用UNUserNotificationCenter.current().delegate = self,则在后台正确触发了委托方法。

func application(_ application: UIApplication,
                     didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                     fetchCompletionHandler completionHandler: @escaping FetchCompletionHandler) {
        print("didReceiveRemoteNotification... \(userInfo)")
}

如何使用“ didReceive”?我想在后台处理通知。

3 个答案:

答案 0 :(得分:1)

当应用程序收到静默推送通知时,将调用

application(_:didReceiveRemoteNotification:fetchCompletionHandler:)。当应用程序处于后台状态时,可以传递静默的推送通知,iOS唤醒应用程序以执行用户不可见的后台处理。

静默推送通知的content-available标志设置为1。

静默推送通知中不应包含警报,徽章或声音。静默推送并不是用户可见的,它只是向应用程序暗示新的远程内容可用。

从推送通知有效负载中删除content-available标志将使iOS将其作为常规通知进行处理。将调用用户通知中心委托方法,而不是application(_:didReceiveRemoteNotification:fetchCompletionHandler:),但是您的应用程序将无法执行由通知触发的后台处理。

您可以使用this tool

验证推送通知有效内容的内容,以解决此类问题

答案 1 :(得分:0)

这是我在应用程序中处理推送通知的方式。我认为您需要实现所有这些方法,才能在前台和后台模式下处理所有iOS版本。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    if #available(iOS 10.0, *) {
        let center  = UNUserNotificationCenter.current()
        center.delegate = self
        center.requestAuthorization(options: [.sound,.alert,.badge], completionHandler: { (granted, error) in
            if error == nil {
                DispatchQueue.main.async {
                    application.registerForRemoteNotifications()
                }
            }
        })
    }
    else {
        let notificationTypes: UIUserNotificationType = [UIUserNotificationType.alert, UIUserNotificationType.badge, UIUserNotificationType.sound]
        let pushNotificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: nil)
        application.registerUserNotificationSettings(pushNotificationSettings)
        application.registerForRemoteNotifications()
    }

}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
    print(deviceTokenString)
}

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    print("Failed to get token; error: \(error)")
}

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    completionHandler([.alert,.sound])
     //do sth
}

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
     //do sth
}

// for iOS < 10
func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
}

答案 2 :(得分:-1)

有UNUserNotificationCenterDelegate的方法:

  • willPresent:当您的应用程序位于前台时,当您收到通知时,将调用此方法。如果应用程序在后台运行,则不会调用此方法。

  • didRecieve:当用户单击通知时调用此方法。

在后台状态下,当用户单击通知时,只会调用“ didRecieve”。