将图像附加到给定图像的通知 URL

Attach image to notification given image URL

我想在给定图像 URL 的情况下将图像附加到我的本地通知。这是创建附件的扩展:

import UserNotifications

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

当我安排新通知时,我是这样使用的:

// url of the image such as http://www.unsplash.com/image.png
let data = try? Data(contentsOf: url) 
guard let myImage = UIImage(data: data!) else { return }

if let attachment = UNNotificationAttachment.create(identifier: key, image: myImage, options: nil) {
    content.attachments = [attachment]
}

创建这样的通知会使应用程序冻结几秒钟,因为应用程序会同步下载图像。我也尝试过使用 DispatchQueue 但它没有改变任何东西。我做错了什么?

您的代码下载图像,对其进行解析以创建 UIImage,将图像转换回 PNG 数据块,然后将此数据写入临时文件。

您可以跳过创建 UIImage 并将其转换回文件的步骤。

尝试使用 URLSessionURLDataTask:

let fileURL = ...
let task = URLSession.shared.dataTask(with: url) { (data, _, _) in
    do {
        try imageData.write(to: fileURL)
        let attachment = UNNotificationAttachment.create(identifier: key, image: myImage, options: nil)
        // call closure to call back with attachment and/or error
    }
    catch let ex {
        // call closure with error
    }
}
task.resume()

我遗漏了一些错误处理和其他细节,但这应该让您大致了解异步执行它需要什么。 URLSessions 使用 GCD 执行异步网络。

使用 Alamofire 异步下载图像,然后尝试显示它。

let destination: DownloadRequest.DownloadFileDestination = {
    _, _ in
    var documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    documentsURL.appendPathComponent("image.jpg")
    return (documentsURL, [.removePreviousFile, .createIntermediateDirectories])
}
Alamofire.download(url, to: destination).response {
    response in
    // do whatever you want with your image, for example if it is an audio file:
    do {
        self.player = try AVAudioPlayer(contentsOf: URL(string: "\(response.destinationURL!)")!)
        self.player.volume = 1.0
        self.player.play()
    } catch {
        print(error)
    }        
}