【问题标题】:Why notification service extension is not firing on iOS 14?为什么通知服务扩展没有在 iOS 14 上触发?
【发布时间】:2021-05-21 09:33:58
【问题描述】:

我集成了UNNotificationServiceExtension,它允许我在推送通知标题呈现给用户之前更改它。

我已遵循apple developer documentation 中提到的指导方针,并在 SO 上浏览了相关问题,但似乎没有任何效果。


按照指示,我已遵循这些准则

  • 在您的推送通知负载中包含 "mutable-content": 1
  • 应正确设置扩展的部署目标(应与主应用目标匹配)
  • 有效负载必须包含带有标题、副标题或正文信息的警报字典
  • 推送通知有效负载中的“aps”字典必须包含带有字符串值的键“category”。

问题

收到推送通知时,有时不会触发我的通知服务扩展,主要是在我删除并安装新的应用程序副本时。在这种情况下也不会触发断点。看起来系统忘记触发服务扩展。我选择了正确的扩展方案,而不是主应用程序目标。我的通知标题没有按照我的逻辑更新。

注意:这发生在 iOS 14 上。在 iOS 12 上,它工作正常。这是 iOS 错误吗?

这已经在这些帖子中讨论过。

https://developer.apple.com/forums/thread/67202 https://developer.apple.com/forums/thread/125987

任何帮助将不胜感激。 谢谢

示例代码

我制作了一个示例项目来演示这个问题。可以从Github Repo下载

相关的 WWDC 视频

Best Practices and What’s New in User Notifications

【问题讨论】:

    标签: ios swift push-notification apple-push-notifications


    【解决方案1】:

    您必须修改 UNNotificationRequest 内容部分。下面是我用于通知扩展的代码 sn-p。

    import UserNotifications
    
    class NotificationService: UNNotificationServiceExtension {
    
        var contentHandler: ((UNNotificationContent) -> Void)?
        var bestAttemptContent: UNMutableNotificationContent?
    
        override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
            self.contentHandler = contentHandler
            bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
            
            if let bestAttemptContent = bestAttemptContent {
                var urlString:String? = nil
                if let urlImageString = request.content.userInfo["urlImageString"] as? String {
                    urlString = urlImageString
                }
                // You can set what ever title you want to set
                bestAttemptContent.title = "Your custom tile goes here"
                if urlString != nil, let fileUrl = URL(string: urlString!) {
                    print("fileUrl: \(fileUrl)")
                    
                    guard let imageData = NSData(contentsOf: fileUrl) else {
                        contentHandler(bestAttemptContent)
                        return
                    }
                    guard let attachment = UNNotificationAttachment.saveImageToDisk(fileIdentifier: "image.jpg", data: imageData, options: nil) else {
                        print("error in UNNotificationAttachment.saveImageToDisk()")
                        contentHandler(bestAttemptContent)
                        return
                    }
                    
                    bestAttemptContent.attachments = [ attachment ]
                }
                
                contentHandler(bestAttemptContent)
            }
        }
        
        override func serviceExtensionTimeWillExpire() {
            if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
                contentHandler(bestAttemptContent)
            }
        }
    
    }
    
    @available(iOSApplicationExtension 10.0, *)
    extension UNNotificationAttachment {
        
        static func saveImageToDisk(fileIdentifier: String, data: NSData, options: [NSObject : AnyObject]?) -> UNNotificationAttachment? {
            let fileManager = FileManager.default
            let folderName = ProcessInfo.processInfo.globallyUniqueString
            let folderURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(folderName, isDirectory: true)
            
            do {
                try fileManager.createDirectory(at: folderURL!, withIntermediateDirectories: true, attributes: nil)
                let fileURL = folderURL?.appendingPathComponent(fileIdentifier)
                try data.write(to: fileURL!, options: [])
                let attachment = try UNNotificationAttachment(identifier: fileIdentifier, url: fileURL!, options: options)
                return attachment
            } catch let error {
                print("error \(error)")
            }
            
            return nil
        }
    }
    

    我使用过的 JSON 负载

    {
      "aps": {
        "alert": {
          "title": "title",
          "body": "Your message Here"
        },
        "mutable-content": 1
      },
      "urlImageString": "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg"
    }
    

    使用您的代码仓库,我得到的输出如下

    如果你想调试通知服务扩展,那么你必须从下拉列表中选择通知服务扩展方案,然后你的断点将为你工作

    【讨论】:

    • 感谢您的回复。我添加了指向 Github 存储库的链接。我已经在修改 UNNotificationRequest。请看示例代码
    • 请在iOS 14上测试。此外,请删除并重新安装应用程序,然后发送通知以重现此问题。您可以多次执行此操作,并且将重现该问题。删除并重新安装应用后确保使用最新的推送通知令牌
    【解决方案2】:

    更新

    我已为此问题提交了Techinical support Incident。我对通知服务扩展进行了广泛的研发。根据苹果文档在 vanila 项目中实现它。我们的配置和一切似乎都是正确的。所以我就这个问题请求了苹果技术支持并得到了回复。

    我们已确定您遇到此问题是由于 iOS 中的错误。 请使用以下方法提交有关此问题的完整错误报告 反馈助理 (https://feedbackassistant.apple.com)。更多 有关反馈助手的信息,请访问 https://developer.apple.com/bug-reporting/.

    请将您提供给我的所有信息再次包含在 错误报告(您可以将日志直接附加到错误报告中)。请务必按照https://developer.apple.com/bug-reporting/profiles-and-logs/ 的说明,并按照 APNS(Apple Push Notification Service)的说明在您的设备上安装日志配置文件,并确保在重现问题之前已安装。

    重要提示:在反馈助手中,当提交关于某个问题的错误报告时 macOS、iOS、watchOS 或 tvOS 上的 API/SDK,请选择合适的 API/SDK 区域(在“不在此列表中的其他内容”之后)。

    所以,我要向苹果提交一份错误报告。一旦得到关于错误报告的回复,我将更新此答案。

    【讨论】:

    • 您对此有任何更新吗?我们有类似的问题,在推送通知中添加用于加载图像的通知扩展后,iOS 14.2 中没有通知
    • 我试图重现这个以向苹果提交错误报告。但它没有被复制。我稍后会尝试。顺便说一句,通知来或不来是另一回事。在我的情况下,通知总是会出现,但我的服务扩展没有做它的工作
    • 我相信我也遇到了同样的问题。你设法让它工作吗?或者你能确认这是一个 iOS 错误吗?
    • @Alexis 正如您在我的回答中看到的,这些是苹果技术支持的话。他们确认这是 iOS 中的一个错误,并告诉我提交错误报告。我还没有提交错误报告。
    • 嗨@AwaisFayyaz,有什么更新吗?最近我的许多客户都报告了类似的问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-13
    • 1970-01-01
    • 2022-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多