有时使用 UNUserNotificationCenter 从远程通知中清空内容图像

Posted

技术标签:

【中文标题】有时使用 UNUserNotificationCenter 从远程通知中清空内容图像【英文标题】:Sometimes empty content image from remote notification using UNUserNotificationCenter 【发布时间】:2017-06-12 17:31:13 【问题描述】:

我正在使用 Apple 去年在 ios 10 中宣布的一项功能。我有一个问题,我的通知中的图像有时是空的。

这是我的UNNotificationServiceExtension.. 我不太确定我做错了什么。图像的大小很小,最大为 1 MB。我来自服务器的有效负载是正确的。

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 
            // Setting the category associated with the notification
            if let category = bestAttemptContent.userInfo["category"] as? String 
                bestAttemptContent.categoryIdentifier = category
            

            // Fetching luubra if available
            if let attachmentString = bestAttemptContent.userInfo["image"] as? String,
                let attachmentUrl = URL(string: attachmentString) 

                let session = URLSession(configuration: URLSessionConfiguration.default)
                let attachmentDownloadTask = session.downloadTask(with: attachmentUrl,
                                                                  completionHandler:  url, _, error in
                        if let error = error 
                            print("Error downloading notification image: \(error)")
                         else if let url = url 
                            do 
                                let attachment = try UNNotificationAttachment(identifier: attachmentString,
                                                                              url: url,
                                                                              options: [UNNotificationAttachmentOptionsTypeHintKey: kUTTypeJPEG])
                                bestAttemptContent.attachments = [attachment]
                             catch let e 
                                print("Error creating NotificationAttachment: \(e)")
                            
                        
                        print("Remote notification content: \(bestAttemptContent)")
                        contentHandler(bestAttemptContent)
                )
                attachmentDownloadTask.resume()

            
        
    

    override func serviceExtensionTimeWillExpire() 
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler,
            let bestAttemptContent =  bestAttemptContent 
            contentHandler(bestAttemptContent)
        
    


【问题讨论】:

【参考方案1】:

Apple 似乎会设置直接关联的类别,如标题或正文内容。 将媒体临时保存到磁盘很重要。因为iOS需要一些时间来下载媒体文件。 iOS 将处理其余部分。

这对我来说很棒。

class NotificationService: UNNotificationServiceExtension 

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

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

        self.contentHandler = contentHandler
        self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        func failed() 
            contentHandler(request.content)
        

        guard let contentHandler = self.contentHandler, let bestAttemptContent = self.bestAttemptContent else 
            return failed()
        

        // Get the image from the User Payload
        guard let imageURLString = request.content.userInfo["image"] as? String else 
            return failed()
        

        guard let imageURL = URL(string: imageURLString) else 
            return failed()
        

        // Download the Image Async
        URLSession.shared.downloadTask(with: imageURL)  (path, _, error) in

            if let error = error 
                print(error.localizedDescription)
            

            if let path = path 

                // Save the image temporary to the disk
                let tmpDirectory = NSTemporaryDirectory()
                let tmpFile = "file://".appending(tmpDirectory).appending(imageURL.lastPathComponent)
                guard let tmpURL = URL(string: tmpFile) else  return 
                try? FileManager.default.moveItem(at: path, to: tmpURL)

                // Add the attachment to the notification content
                if let attachment = try? UNNotificationAttachment(identifier: "", url: tmpURL) 
                    bestAttemptContent.attachments = [attachment]
                
            

            // Serve the notification content
            contentHandler(bestAttemptContent)

        .resume()

    

    override func serviceExtensionTimeWillExpire() 
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler,
            let bestAttemptContent =  bestAttemptContent 
            contentHandler(bestAttemptContent)
        
    

【讨论】:

以上是关于有时使用 UNUserNotificationCenter 从远程通知中清空内容图像的主要内容,如果未能解决你的问题,请参考以下文章

如何通过应用程序扩展(iWatch)取消预定的本地通知(在 iPhone 上)

MySQL 有时不使用 INDEX 但有时会使用

为啥使用 == 比较两个整数有时有效,有时无效? [复制]

在 C++ 中,迭代器,为啥有时我使用它,有时使用 *it?

Worklight Studio 和本地开发,有时无法使用 Java 类,有时无法使用 HTML 文件

使用 IPython.display.image 显示来自网络的图像:有时有效,有时无效