ios - 有时使用 UNUserNotificationCenter 来自远程通知的空内容图像

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

我正在使用 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)
        }
    }

}

最佳答案

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)
        }
    }
}

关于ios - 有时使用 UNUserNotificationCenter 来自远程通知的空内容图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44505429/

相关文章:

iphone - UILabel 不会更改 setFrame 上的高度

ios - 如何使用 Xcode 在 Swift 中对字符串进行 AES 128 加密并将其作为 POST 发送到服务器?

android - 使用 GCM 时获得 GET_ACCOUNTS 权限 - 为什么需要这样做?

ios - 在没有推送通知的情况下使用 Parse

ios - UITableView 在用户释放之前重置到开始位置

objective-c - 分配简单 bool 值时的 EXC_BAD_ACCESS

objective-c - xcode 在同一窗口中打开 "click here to view symbol declaration"

ios - 根据获取的属性对实体进行排序

ios - 更改 View + 以编程方式将变量发送到 View

ios 如何在推送通知中启动应用程序