1

我正在 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 应用程序的情况下运行”

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

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

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

4

2 回答 2

1

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

apns-push-type
于 2020-04-28T13:18:28.813 回答
1

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

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

于 2020-04-28T12:59:11.270 回答