使用UIImage或远程URL进行UNNotificationAttachment

Mar*_*Him 14 uiimage ios swift unnotificationattachment

在我,Notification Service Extension我正在从URL下载图像,以显示UNNotificationAttachment在通知中.

所以我把这个图像作为UIImage,并没有看到需要在光盘上的我的app目录/组容器中写它只是为了设置通知.

有没有一个很好的方法创建UNNotificationAttachment一个UIImage? (应该适用于本地和远程通知)

Mar*_*Him 25

  1. 在tmp文件夹中创建目录
  2. NSData表示写入UIImage新创建的目录
  3. 使用url创建UNNotificationAttachment到tmp文件夹中的文件
  4. 清理tmp文件夹

我写了一个扩展 UINotificationAttachment

extension UNNotificationAttachment {

    static func create(identifier: String, image: UIImage, options: [NSObject : AnyObject]?) -> UNNotificationAttachment? {
        let fileManager = FileManager.default
        let tmpSubFolderName = ProcessInfo.processInfo.globallyUniqueString
        let tmpSubFolderURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(tmpSubFolderName, isDirectory: true)
        do {
            try fileManager.createDirectory(at: tmpSubFolderURL, withIntermediateDirectories: true, attributes: nil)
            let imageFileIdentifier = identifier+".png"
            let fileURL = tmpSubFolderURL.appendingPathComponent(imageFileIdentifier)
            guard let imageData = UIImagePNGRepresentation(image) else {
                return nil
            }
            try imageData.write(to: fileURL)
            let imageAttachment = try UNNotificationAttachment.init(identifier: imageFileIdentifier, url: fileURL, options: options)
            return imageAttachment
        } catch {
            print("error " + error.localizedDescription)
        }
        return nil
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,要建立UNUserNotificationRequestUNUserNotificationAttachmentUIImage你可以简单地折腾这样的

let identifier = ProcessInfo.processInfo.globallyUniqueString
let content = UNMutableNotificationContent()
content.title = "Hello"
content.body = "World"
if let attachment = UNNotificationAttachment.create(identifier: identifier, image: myImage, options: nil) {
    // where myImage is any UIImage that follows the 
    content.attachments = [attachment] 
}
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 120.0, repeats: false)
let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { (error) in
    // handle error
}
Run Code Online (Sandbox Code Playgroud)

这应该工作,因为UNNotificationAttachment将图像文件复制到自己的位置.

  • 我没有看到"第4步清理tmp文件夹" (5认同)
  • 使用临时文件夹,由系统自动清理其未清理的缓存目录 (2认同)
  • 请注意,iOS 会自动将文件移动到附件数据存储中,因此该文件将立即从临时目录中删除。您无需担心清理问题。 (2认同)

Ant*_*ine 6

我已经创建了一个关于这个主题的博客文章,专注于GIF图像.但是为简单的图像重写我的代码应该很容易.

您需要创建通知服务扩展: 通知服务扩展

并包含此代码:

final class NotificationService: UNNotificationServiceExtension {

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

    override internal func didReceiveNotificationRequest(request: UNNotificationRequest, withContentHandler contentHandler: (UNNotificationContent) -> Void){
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        func failEarly() {
            contentHandler(request.content)
        }

        guard let content = (request.content.mutableCopy() as? UNMutableNotificationContent) else {
            return failEarly()
        }

        guard let attachmentURL = content.userInfo["attachment-url"] as? String else {
            return failEarly()
        }

        guard let imageData = NSData(contentsOfURL:NSURL(string: attachmentURL)!) else { return failEarly() }
        guard let attachment = UNNotificationAttachment.create("image.gif", data: imageData, options: nil) else { return failEarly() }

        content.attachments = [attachment]
        contentHandler(content.copy() as! UNNotificationContent)
    }

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

}

extension UNNotificationAttachment {

    /// Save the image to disk
    static func create(imageFileIdentifier: String, data: NSData, options: [NSObject : AnyObject]?) -> UNNotificationAttachment? {
        let fileManager = NSFileManager.defaultManager()
        let tmpSubFolderName = NSProcessInfo.processInfo().globallyUniqueString
        let tmpSubFolderURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(tmpSubFolderName, isDirectory: true)

        do {
            try fileManager.createDirectoryAtURL(tmpSubFolderURL!, withIntermediateDirectories: true, attributes: nil)
            let fileURL = tmpSubFolderURL?.URLByAppendingPathComponent(imageFileIdentifier)
            try data.writeToURL(fileURL!, options: [])
            let imageAttachment = try UNNotificationAttachment.init(identifier: imageFileIdentifier, URL: fileURL!, options: options)
            return imageAttachment
        } catch let error {
            print("error \(error)")
        }

        return nil
    }
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请访问:http: //www.avanderlee.com/ios-10/rich-notifications-ios-10/

  • 尽管此链接可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。如果链接的页面发生更改,仅链接的答案可能会失效。有关更多详细信息,请参见[answer]。 (2认同)
  • 系统修剪临时目录本身. (2认同)