UNUserNotificationCenter didReceive 没有被调用

toa*_*ast 4 ios swift

当我发送推送通知时,应用程序在前台willPresent被调用。didReceive永远不会被调用。当应用程序在后台并收到推送通知时,会显示警报,但应用程序从不调用didReceive、 或willPresent

在 Project > Capabilities 中,我有 Background Modes Location updates,并Remote notifications进行了检查。位置更新用于不相关的代码。

我还启用了推送通知。这工作正常,因为它们正在被接收。

我已经UNUserNotificationCenter在我的 中实现了通知内容AppDelegate,见下文:

import UserNotifications
...

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
...

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

    // MARK: - Push Notifications

    func registerForPushNotifications(application: UIApplication) {
        let notificationCenter = UNUserNotificationCenter.current()
        notificationCenter.delegate = self
        notificationCenter.requestAuthorization(options: [.badge, .sound, .alert], completionHandler: {(granted, error) in
            if (granted)
            {
                UIApplication.shared.registerForRemoteNotifications()
            }
            else{
                //Do stuff if unsuccessful...
                print("Unsuccessful in registering for push notifications")
            }
        })
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        //convert the deviceToken to a string
        let deviceTokenString = deviceToken.map { String(format: "%02.2hhx", arguments: [$0]) }.joined()

        let ud = UserDefaults.standard
        ud.set(deviceTokenString, forKey: "deviceToken")
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        //Handle the notification
        print("User Info = ",notification.request.content.userInfo)
        completionHandler([.alert, .badge, .sound])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        //handle the notification
        print("Push notification: ",response.notification.request.content.userInfo)

        ... code to import the notification data into Core Data.

        completionHandler()
    }

...
}
Run Code Online (Sandbox Code Playgroud)

任何想法为什么didReceive不被调用?

这是收到的推送通知:

[AnyHashable("aps"): {
    alert = "[name] has added you as a friend.";
    category = "NEWS_CATEGORY";
    "related_user_id" = 55;
    sound = default;
    type = "friend_request";
}]
Run Code Online (Sandbox Code Playgroud)

iOS 10.1,斯威夫特 3。

Bla*_*erX 10

didReceive不会在收到通知时执行,而是在用户对收到的通知执行操作时执行

来自 Apple 文档https://developer.apple.com/documentation/usernotifications/unusernotificationcenterdelegate

调用以使您的应用程序知道用户为给定通知选择了哪个操作。

这意味着当用户对收到的通知执行操作(推送通知、向下滑动等)时将调用此方法


bee*_*eee 6

我发现我需要在获得许可后设置委托。

否则,当您第一次使用该应用程序时,您在获得权限之前注册了委托,并且不会触发 didReceive 函数 - 这仅在您第一次运行应用程序时发生,在杀死并重新启动之后,它被调用得很好。

见下文:

 UNUserNotificationCenter.current().requestAuthorization(options: authOptions, completionHandler: { (granted, error) in
        if granted {
            // Register after we get the permissions.
            UNUserNotificationCenter.current().delegate = self
        }
    })
Run Code Online (Sandbox Code Playgroud)


小智 -1

willPresent如果您点击通知横幅,就会调用该方法。

如果您希望在后台处理推送通知而无需点击横幅,那么您应该将 {"content-available":1} 附加到您的通知负载中。这种类型的推送通知称为静默推送。这不会普通推送那样创建通知横幅/警报,您必须自己创建横幅。

当您收到带有“内容可用”的推送通知时,didReceive当应用程序处于后台时,将调用委托方法。

注意:您还必须在UIBackgroundModesplist 文件的密钥中添加“远程通知”。

  • 我认为这个答案中的某些信息不正确。如果应用程序位于前台时收到通知(无需用户交互),则会调用“willPresent”。另外,添加 {"content-available": 1} 并不一定意味着不会有横幅 - 这取决于是否有“alert”字段。苹果文档并不清楚如何将它们一起使用 - 我已经看到它的工作原理。当用户点击横幅时,会调用 UNUserNotificationCenterDelegate 的“didReceive”。 (2认同)