为什么通知服务扩展在 iOS 14 上没有启动?

Awa*_*yaz 5 push-notification apple-push-notifications ios swift

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

\n

我已遵循苹果开发人员文档中提到的指南,并浏览了 SO 的相关问题,但似乎没有任何效果。

\n
\n

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

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

问题

\n

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

\n

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

\n

这些线程中已经对此进行了讨论。

\n

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

\n

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

\n

示例代码

\n

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

\n

相关 WWDC 视频

\n

最佳实践和用户通知中的新增内容\xe2\x80\x99

\n

Vir*_*der 2

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

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
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用过的 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"
}
Run Code Online (Sandbox Code Playgroud)

使用您的代码仓库,我得到的输出是 在此输入图像描述

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