如何根据传入的远程通知有效负载中定义的类别添加不同的操作?迅速更新

Posted

技术标签:

【中文标题】如何根据传入的远程通知有效负载中定义的类别添加不同的操作?迅速更新【英文标题】:How to add different actions depending on the category defined in incoming remote notification payload? Swift UPDATED 【发布时间】:2019-06-13 11:59:45 【问题描述】:

我正在我的两个相关应用程序中实现推送通知,到目前为止,我能够发送通知、设备到设备以及主题。收到通知后,通知会在与有效负载一起发送的 url 处显示图像。我的目标是向主题通知添加操作,并且每个主题的操作都不同。 Ej。 "shop-promotions" 主题通知(即"buy")的操作将不同于“新闻”主题通知(即"play")。所以我想在远程通知的有效负载中发送一个“类别”参数,并使用它来区分不同的传入通知并显示正确的操作集。是否可以在 NotificationExtension.swift didReceive 中定义操作,或者还必须使用自定义 UI 来显示操作? 在https://www.pluralsight.com/guides/creating-ios-rich-push-notifications 中尽可能显示,但我没有成功。

我将它们声明为:

override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) 

        print("NotificationService: dide receive called")
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)


        if let bestAttemptContent = bestAttemptContent 
            if let urlString = bestAttemptContent.userInfo["attachment-url"] as? String,
                let data = NSData(contentsOf: URL(string:urlString)!) as Data? 
                let path = NSTemporaryDirectory() + "attachment"
                _ = FileManager.default.createFile(atPath: path, contents: data, attributes: nil)

                do 
                    let file = URL(fileURLWithPath: path)
                    let attachment = try UNNotificationAttachment(identifier: "attachment", url: file,options:[UNNotificationAttachmentOptionsTypeHintKey : "public.jpeg"])
                    bestAttemptContent.attachments = [attachment]

                 catch 
                    print(error)

                

                // Actions
                if let category = bestAttemptContent.userInfo["category"] as? String 

                    if category == "shop-promotions" 
                        let buy = UNNotificationAction(identifier: "buy", title: "Buy", options: [])
                        let close = UNNotificationAction(identifier: "close", title: "Close", options: [])

                        let category = UNNotificationCategory(identifier: "shop-promotions", actions: [buy,close], intentIdentifiers: ["buy","close"], options: [])
                        UNUserNotificationCenter.current().setNotificationCategories([category])
                    
                

             // else 
            //                if let contentHandler: ((UNNotificationContent) -> Void) =
            //                    self.notificationContentHandler,
            //                    let content: UNNotificationContent = self.notificationContent 
            //                    contentHandler(content)  
    

            let buy = UNNotificationAction(identifier: "buy", title: "Buy", options: [])
            let close = UNNotificationAction(identifier: "close", title: "Close", options: [])

            let category = UNNotificationCategory(identifier: "shop-promotions", actions: [buy,close], intentIdentifiers: [], options: [])
            UNUserNotificationCenter.current().setNotificationCategories([category])


            contentHandler(bestAttemptContent)
        

这是为通知发送的字典:

let postParams: [String : Any] = [
            "to": topic,
            "notification": [
                //                    "badge" : 1, sendig the badge number, will cause aglitch
                "body": body,
                "title": title,
                "subtitle": subtitle,
                "text": "some text",
                "sound" : true, // or specify audio name to play
                "priority": "high",
                "content_available": true,
                "mutable_content": true,
                "category": "shop-promotions"
            ],
            "data" : [
                "attachment-url": dataUrl,
//                "media_type":"image",
                "productId": productId,
                "price": price
            ]
        ]

更新:

    更改了类别声明,将它们放入一个静态函数中,我在检查通知权限后调用 didFinishLaunchingWithOptions,在获取令牌后调用 didRegisterForRemoteNotificationsWithDeviceToken。 设置NotificationServiceinfo.plist 不带任何UNNotificationExtensionCategory,因为我看到这是在NotificationContentinfo.plist 中。 为NotificationService.swiftinfo.plist 尝试了不同的Target Membership 设置。什么是正确的配置?

仍然是只显示通知的图像。

您能看到正确设置缺少什么吗?

actions函数是这样的:

static func configurePushCategories() 
        if #available(iOS 10.0, *) 
            UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.badge,.sound])  (granted:Bool, error:Error?) in
                if error != nil 
                    print(error?.localizedDescription as Any)
                
                if granted 
                    print("Permission granted")
                 else 
                    print("Permission not granted")
                
            

            //  actions

            let buy = UNNotificationAction(identifier: "buy", title: "Buy", options: [.foreground])
            let play = UNNotificationAction(identifier: "play", title: "Play", options: [.foreground])
            let close = UNNotificationAction(identifier: "close", title: "Close", options: [.foreground])

//            let shopPromotionsCategory = UNNotificationCategory(identifier: "shop-promotions", actions: [buy,close], intentIdentifiers: ["buy","close"], options: [])
//            let fixItPromotionsCategory = UNNotificationCategory(identifier: "fix-it-promotions", actions: [buy,close], intentIdentifiers: ["buy","close"], options: [])
//            let cityFixItNewsCategory  = UNNotificationCategory(identifier: "city-fix-it-news", actions: [play,close], intentIdentifiers: ["play","close"], options: [])
//            let countryFixItNewsCategory = UNNotificationCategory(identifier: "country-fix-it-news", actions: [play,close], intentIdentifiers: ["play","close"], options: [])

            let shopPromotionsCategory = UNNotificationCategory(identifier: "shop-promotions", actions: [buy,close], intentIdentifiers: [], options: [])

            let fixItPromotionsCategory = UNNotificationCategory(identifier: "fix-it-promotions", actions: [buy,close], intentIdentifiers: [], options: [])

            let cityFixItNewsCategory  = UNNotificationCategory(identifier: "city-fix-it-news", actions: [play,close], intentIdentifiers: [], options: [])

            let countryFixItNewsCategory = UNNotificationCategory(identifier: "country-fix-it-news", actions: [play,close], intentIdentifiers: [], options: [])

            UNUserNotificationCenter.current().setNotificationCategories([shopPromotionsCategory,fixItPromotionsCategory, cityFixItNewsCategory, countryFixItNewsCategory])
         else 
            // Fallback on earlier versions
        
    

【问题讨论】:

您需要针对您的类别在 AppDelegate 的 didFinishLaunchingWithOptions 中注册您的通知类别。将您的代码移动到 didFinishLaunchingWithOptions let buy = UNNotificationAction(identifier: "buy", title: "Buy", options: []) let close = UNNotificationAction(identifier: "close", title: "Close", options: []) let category = UNNotificationCategory(identifier: "shop-promotions", actions: [buy,close], intentIdentifiers: [], options: []) UNUserNotificationCenter.current().setNotificationCategories([category]) 当您的推送服务器想要向用户发送通知时,它可以将具有适当值的类别键添加到通知的有效负载中。当 iOS 看到带有类别键的推送通知时,它会查找应用程序注册的类别。如果 iOS 找到匹配项,它会在通知中显示相应的操作。 @Milan 我确实按照你们的建议进行了更改,请参阅更新问题,但我仍然处于同样的情况,你能看出它有什么问题吗? @iMHiteshSurani 我执行了更改,现在设置为您在答案中列举的四个步骤,但没有任何改变。 【参考方案1】:

终于找到了所有更改后未显示操作的原因。在字典中"category": "someValue" 需要声明为"click_action":"someValue"..因为它去了 Firebase.. 不确定我是否同意这个选择..也许这只是为了给开发人员原本无聊的生活增添趣味..谢谢火力基地.. 除了讽刺,也非常感谢您对此的帮助。

【讨论】:

这是因为 Firebase 的有效负载用于为所有支持的平台构建通知,而“类别”是 Apple 特定的键。要为 Apple 自定义 Firebase 的消息,您需要包括以下内容:"apns": "payload": "category": "someValue" Payload 对象是 Apple 的有效负载,您可以在其中放置“aps”、“category”和其他内容。否则,您在顶层使用“click_action”,以便 Firebase 正确地将其转换为所有平台中的相关键(“click_action”实际上是 android 版本的“category”)【参考方案2】:

Apple documentation states:

当您的推送服务器想要向用户发送通知时,它可以 将具有适当值的类别键添加到通知的 有效载荷。当 iOS 看到带有类别键的推送通知时,它 查找应用程序注册的类别。如果 iOS 发现 匹配时,它会在通知中显示相应的操作。

#Notification 负载:

 
    "aps": 
        "category": "MEETING_INVITATION",
        "alert": 
            "title": "Weekly Staff Meeting",
            "body": "Every Tuesday at 2 pm"
        
    ,
    "MEETING_ID": "123456789",
    "USER_ID": "ABCD1234"

要支持可操作的通知,您必须:

在您的 iOS 应用启动时声明一个或多个通知类别。

为您的通知类别分配适当的操作。

处理您注册的所有操作。

在生成通知时将类别标识符分配给通知负载。

【讨论】:

哦,我明白了。如果您使用带有通知内容扩展的自定义 ui,您将不得不在 didReceive(_ responsein NotificationViewController 中声明响应,所以我认为这些操作有要在 NotificationService.swift 中声明,因为我遵循的教程是在那里声明它们让我走错了方向。所以我可以避免在 info.plistright 中设置类别字典吗?非常感谢。

以上是关于如何根据传入的远程通知有效负载中定义的类别添加不同的操作?迅速更新的主要内容,如果未能解决你的问题,请参考以下文章

多个类别名称未显示通知内容扩展?

推送通知使用有效负载打开正确的页面

iOS 从远程通知打开时使用不同的启动画面?

无声推送通知有效负载

当我的应用程序处于后台或关闭时,当远程推送通知到达时从有效负载中获取数据

ios8自定义交互式推送通知