代码之家  ›  专栏  ›  技术社区  ›  Awais Fayyaz

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

  •  0
  • Awais Fayyaz  · 技术社区  · 3 年前

    我已经融入 UNNotificationServiceExtension 这允许我在推送通知呈现给用户之前更改推送通知标题。

    我遵循了中提到的指导方针 apple developer documentation 也浏览了SO上的相关问题,但似乎什么都没用。


    按照指示,我遵循了这些指导方针

    • 在推送通知有效负载中包含“可变内容”: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

    0 回复  |  直到 3 年前
        1
  •  3
  •   user160917    1 年前

    唯一对我有效的解决方案(21/07/2023)是:

    1. 取消选中“安装时复制”。
    2. 从“Frameworks”中删除通知服务扩展,然后重新添加(重新启动iPhone)。
        2
  •  2
  •   Virender    3 年前

    您必须修改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
        }
    }
    

    我使用的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"
    }
    

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

    如果要调试NotificationService扩展,则必须从下拉列表中选择NotificationService扩展方案,然后断点将为您工作

        3
  •  1
  •   Awais Fayyaz    3 年前

    更新

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

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

    请再次将您提供给我的所有信息纳入 bug报告(您可以将日志直接附加到bug报告中)。请务必遵循以下说明 https://developer.apple.com/bug-reporting/profiles-and-logs/ 并按照APNS(Apple推送通知服务)的说明在您的设备上安装日志记录配置文件,并确保在重现问题之前已安装。

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

    因此,我将提交一份 错误报告 苹果。一旦收到bug报告的回复,我将更新此答案。