通过 NodeJS 发送推送看不到操作按钮甚至通知

Cannot see action buttons even notification by sending push via NodeJS

我也看不到通知操作,甚至在 nodeJS 以下发送时也无法推送通知警报。从像这样的相同 nodeJS 配置发送简单警报没有问题:

notification.alert = 'Hello World \u270C';

我看到本地预定通知的警报操作:

self.scheduleNotification(event: "test", interval: 3)

很高兴知道我在通知负载方面做错了什么。

AppDelegate.swift 文件:

import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        let center = UNUserNotificationCenter.current()
        center.delegate = self

        center.requestAuthorization(options: [.alert, .sound, .badge]) { (status: Bool, error: Error?) in
            if error == nil {
                self.registerCategory()
                // Now, I can see action buttons for that scheduled notification, but not from payload (nodeJS)
                self.scheduleNotification(event: "test", interval: 3)
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
                print("Push registration success.")
            }
            else {
                print("Push registration failed:")
                print(error!.localizedDescription)
            }
        }

        return true
    }

    func registerCategory() -> Void {

        let acceptAction = UNNotificationAction(identifier: "ACCEPT_ACTION",
                                                title: "Accept",
                                                options: UNNotificationActionOptions(rawValue: 0))
        let declineAction = UNNotificationAction(identifier: "DECLINE_ACTION",
                                                 title: "Decline",
                                                 options: UNNotificationActionOptions(rawValue: 0))

        let category : UNNotificationCategory = UNNotificationCategory.init(identifier: "MEETING_INVITATION", actions: [acceptAction, declineAction], intentIdentifiers: [], options: [])

        let center = UNUserNotificationCenter.current()
        center.setNotificationCategories([category])

    }

    func scheduleNotification (event : String, interval: TimeInterval) {
        let content = UNMutableNotificationContent()

        content.title = event
        content.body = "body"
        content.categoryIdentifier = "MEETING_INVITATION"
        let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: interval, repeats: false)
        let identifier = "id_" + event
        let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)

        let center = UNUserNotificationCenter.current()
        center.add(request, withCompletionHandler: { (error) in
        })
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let token = deviceToken.map { String(format: "%02.2hhx", [=12=]) }.joined()
        print("Handled deviceToken: ")
        print(token)
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        completionHandler()
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler(.alert)
    }
}

app.js 文件:

var apn = require('apn')
var util = require('util')

// Set up apn with the APNs Auth Key:
var apnProvider = new apn.Provider({  
     token: {
        key: '____', // Path to the key p8 file
        keyId: '____', // The Key ID of the p8 file (available at https://developer.apple.com/account/ios/certificate/key)
        teamId: '____', // The Team ID of your Apple Developer Account (available at https://developer.apple.com/account/#/membership/)
    },
    production: false // Set to true if sending a notification to a production iOS app
});

// Enter the device token from the Xcode console:
var deviceToken = '____';

// Prepare a new notification:
var notification = new apn.Notification();

// Bundle ID:
notification.topic = '____'; 

// It works:
notification.category = "MEETING_INVITATION";
notification.alert = {"title":"React with push","body":"Tap to see actions about that push."};

// It doesn't work:
// notification.payload = {"aps":{"category":"MEETING_INVITATION","alert":{"title":"React with push","body":"Tap to see actions about that push."}}};

apnProvider.send(notification, deviceToken).then(function(result) {  
    // Check the result for any failed devices
    console.log(util.inspect(result, true, 7, true));
});

我认为你需要实现这个方法:

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
  //do some data processing if needed
  completion(.alert)
}

因为 UNUserNotificationCenter 应该处理此类通知,而不是 AppDelegate。请注意它是 UNUserNotificationCenterDelegate 协议的一部分。希望这会有所帮助

我已经通过使用 nodeJS 模块的另一个属性解决了我的问题,如下所示:

notification.category = "MEETING_INVITATION";
notification.alert = {"title":"React with push","body":"Tap to see actions about that push."};

但是 aps 类型的有效负载(仅限内容)仍然存在问题:

notification.payload = {"aps":{"category":"MEETING_INVITATION","alert":{"title":"React with push","body":"Tap to see actions about that push."}}};

这就是为什么,我离开了那个 node js 模块。我发现了一些不错的 Mac AppStore APNS 应用程序。其中一个做得很好,符合我的预期。也许我们也可以用nodeJS解决它,但我找不到它。