watchOS,不接收远程通知

Posted

技术标签:

【中文标题】watchOS,不接收远程通知【英文标题】:watchOS, not receiving remote notifications 【发布时间】:2020-03-11 10:29:50 【问题描述】:

我正在 WatchOS 6 上开发应用程序,但我无法收到远程通知

这是我在 ExtensionDelegate 中推送通知的注册码,我正在获取有效的设备令牌。

extension ExtensionDelegate 

    func setupRemoteNotifications() 

        UNUserNotificationCenter.current().delegate = self

        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound])  (granted, error) in

            print("[WATCH PUSH NOTIFICATIONS] Permission granted: \(granted)")

            guard granted else 
                DispatchQueue.main.async 
                    self.showNotificationsNotGrantedAlert()
                    return
                
                return
            

            self.getNotificationSettings()
        
    

    private func getNotificationSettings() 

        UNUserNotificationCenter.current().getNotificationSettings  settings in

            print("[WATCH PUSH NOTIFICATIONS] Notification settings: \(settings)")

            guard settings.authorizationStatus == .authorized else  return 

            DispatchQueue.main.async 
                WKExtension.shared().registerForRemoteNotifications()
                self.onRemoteNotificationRegistration()
            
        
    

    private func onRemoteNotificationRegistration()  

    func didRegisterForRemoteNotifications(withDeviceToken deviceToken: Data) 

        // Convert token to string
        let deviceTokenString = deviceToken.map  data in String(format: "%02.2hhx", data) .joined()

        print("[WATCH PUSH NOTIFICACTIONS] Device Token: \(deviceTokenString)")

        UserSettings.shared.deviceToken = deviceTokenString
    

    func didFailToRegisterForRemoteNotificationsWithError(_ error: Error) 
        print("[WATCH PUSH NOTIFICATIONS] Failed to register device: \(error)")
        UserSettings.shared.deviceToken = nil
    

    func didReceiveRemoteNotification(_ userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (WKBackgroundFetchResult) -> Void) 

        print("[WATCH PUSH NOTIFICATIONS] Push notification received: \(userInfo)")

        let aps = userInfo["aps"] as! [String: AnyObject]

        completionHandler(.noData)
    


extension ExtensionDelegate: UNUserNotificationCenterDelegate 

    // show notification also when in foreground
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) 

        print("[WATCH PUSH NOTIFICATION] Will present notification...")

        let categoryIdentifier = notification.request.content.categoryIdentifier
        let category = NotificationCategory(rawValue: categoryIdentifier)

        if category == NotificationCategory.NotificationCategory 

         else if category == NotificationCategory.ActivityCategory 

        

        completionHandler([.alert, .badge, .sound])
    


    // called when tapped onto notification banner
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) 
        print("[WATCH PUSH NOTIFICATION] Did receive notification response")

        let userInfo = response.notification.request.content.userInfo as! [String: AnyObject]

        let aps = userInfo["aps"] as! [String: AnyObject]

        let categoryIdentifier = response.notification.request.content.categoryIdentifier
        let category = NotificationCategory(rawValue: categoryIdentifier)

        if category == NotificationCategory.NotificationCategory 

         else if category == NotificationCategory.ActivityCategory 

        

        handleNotificationAction(response.actionIdentifier)
        openNotification(userInfo: userInfo)

        completionHandler()
    



extension ExtensionDelegate 

    private func handleNotificationAction(_ actionIdentifier: String) 

        let action = NotificationAction(rawValue: actionIdentifier)
        if action == NotificationAction.Call 
            print("Action: Call handled!")
         else if action == NotificationAction.Email 
            print("Action: Email handled!")
         else if action == NotificationAction.Message 
            print("Action: Message handled!")
        
    

    private func openNotification(userInfo: [String: AnyObject]) 
        // let something = userInfo["something"] ...
    


extension ExtensionDelegate 

    private func showNotificationsNotGrantedAlert() 

        let settingsActionTitle = NSLocalizedString("Settings", comment: "")
        let cancelActionTitle = NSLocalizedString("Cancel", comment: "")
        let message = NSLocalizedString("You need to grant a permission from notification settings.", comment: "")
        let title = NSLocalizedString("Push Notifications Off", comment: "")

        let settingsAction = WKAlertAction(title: settingsActionTitle, style: .default) 

            print("[WATCH PUSH NOTIFICATIONS] Go to Notification Settings")
        

        let cancelAction = WKAlertAction(title: cancelActionTitle, style: .cancel) 
            print("[WATCH PUSH NOTIFICATIONS] Cancel to go to Notification Settings")
        

        WKExtension.shared().rootInterfaceController?.presentAlert(withTitle: title, message: message, preferredStyle: .alert, actions: [settingsAction, cancelAction])
    

我在 WatchExtensions 中添加了推送通知权利

我正在使用有效的 TeamId、P8 证书、P8 密钥、捆绑 ID 从 Push Notification Tester 应用程序发送通知 -> 我正在取得成功。

我发送默认测试通知没什么特别的


    "aps": 
        "alert": 
            "title": "Silver Salmon Creek",
            "body": "You are within 5 miles of Silver Salmon Creek."
        ,
        "category": "Notification"
    

我有类似的 ios 代码,并且通知在 iPhone 上正确传递。

更新

我已经测试了更多

我已将应用程序添加到我的 iPhone 应用程序中 但 iPhone 应用程序适用于 iOS 13 Watch 应用适用于 WatchOS 6

据我了解,这款 WatchOS 应用可以作为独立应用安装。

我已勾选“支持在未安装 iOS 应用的情况下运行”

据我了解,我的服务器应该将此通知发送给双方 手表设备令牌和 iOS 设备令牌。如果有重复的通知将通知发送到哪里,即发送到 iPhone / watchOS,APNS/iOS/watchOS 会做出决定。 如果只有 watchOS 应用程序,我认为它将被传递到 watch Device 令牌 如果同时存在手表/iOS应用程序,那么它将发送到iOS,然后发送到设备,无论用户是否在给定时刻使用iPhone/Watch,并将其发送到当前使用的设备。

所以现在,如果我使用 iOS 捆绑标识符向 iPhone 设备令牌发送通知,并锁定 iPhone 并在手腕上观看,我会在 WatchOS 上收到通知,甚至可以查看带有动态内容的长通知。

但是,当我卸载 iOS 版本的应用程序,并使用 iPhone 或手表设备令牌和适当的捆绑包 ID iOS/watchOS 发送通知时,对于独立应用程序,我不会再次收到此通知。

【问题讨论】:

【参考方案1】:

我遇到了类似的问题,请确保您的 p8 Bundle ID 使用的是显式 WatchkitApp ID,而不是 Extension 的 ID。

一旦我删除了 .watchkitextension 并卸载(应用程序)、重新安装、重新注册设备,它就可以工作了。

【讨论】:

我发现了问题。它与使用 node-apns 从服务器发送推送通知的方式有关。我也有旧的推送通知测试器应用程序。需要 3.0 版本的 node-apns。有额外的 Header 字段发送到 APNS 服务器【参考方案2】:

我发现了问题。它与使用 node-apns 从服务器发送推送通知的方式有关。我也有旧的推送通知测试器应用程序。需要 3.0 版本的 node-apns。有额外的 Header 字段发送到 APNS 服务器

apns-push-type

【讨论】:

以上是关于watchOS,不接收远程通知的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Iphone 的远程通知传递给 Watch OS?

Swift:如何从服务器接收远程通知?

注册以接收远程 CloudKit 更改的通知不起作用

在后台模式下接收远程推送通知是不是可以多次振动?

APNS:如果应用程序被强制退出,则接收静默远程通知

在 ios 中处理远程通知接收