UNNotificationAttachment 无法附加图像

UNNotificationAttachment failing to attach image

因此,以下代码用于从图像的本地存储 url 附加图像。我检查 Terminal 以查看图像是否已存储并且它确实存储了图像而没有任何问题。因此排除 url 本身的任何问题。

do {
let attachment = try UNNotificationAttachment(identifier: imageTag, url: url, options: nil)
content.attachments = [attachment]
} catch {
print("The attachment was not loaded.")
}

创建 UserNotification 的其他代码工作正常,因为它会在正确的指定时间触发。

代码总是转到 catch 块。如果实施中有任何错误,任何人都可以指出我的错误。请帮忙。谢谢。

编辑:print(error.localizedDescription) 错误消息是 Invalid attachment file URL

Edit2:print(error) 错误消息是 Error Domain=UNErrorDomain Code=100 "Invalid attachment file URL" UserInfo={NSLocalizedDescription=Invalid attachment file URL}

我找到了它背后的真正问题。在 apple 文档中写到 url 应该是 file url 并且因此您可能会遇到问题。

为了解决这个问题,我将图像添加到临时目录,然后添加到 UNNotificationAttachment .

请在下面找到代码。 (对于我的用例,我得到了一个 imageURL)

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

        do {
            try fileManager.createDirectory(at: tmpSubFolderURL!, withIntermediateDirectories: true, attributes: nil)
            let fileURL = tmpSubFolderURL?.appendingPathComponent(imageFileIdentifier)
            try data.write(to: fileURL!, options: [])
            let imageAttachment = try UNNotificationAttachment.init(identifier: imageFileIdentifier, url: fileURL!, options: options)
            return imageAttachment
        } catch let error {
            print("error \(error)")
        }
        return nil
    }
}

该函数参数中的数据为图像数据。下面是我是如何调用这个方法的。

let imageData = NSData(contentsOf: url)
guard let attachment = UNNotificationAttachment.create(imageFileIdentifier: "img.jpeg", data: imageData!, options: nil) else { return  }
            bestAttemptContent?.attachments = [attachment]

我还发现了 UNNotificationAttachment 对象初始化的重要且非常奇怪的行为。我遇到了错误:

"Invalid attachment file URL"

但这并不总是发生。以防万一我将相同的图像用于附件的某些通知。当我为每个附件制作独立的图像副本时,它从未发生过。然后我检查了应该复制图像的目录(因为我想清理它),但我很惊讶没有图像。

似乎 UNNotificationAttachment 初始化进程正在删除给定 URL 秒的文件。因此,当您尝试重用某些图像时,可以删除它们(可能是异步的,因为我正在检查该图像是否存在并且它总是返回 true - 该文件存在)。但是 UNNotificationAttachment 以您在上面看到的错误结束。在我看来,此错误的唯一逻辑解释是在 UNNotificationAttachment 初始化过程中删除了给定 URL 处的文件。

Apple 实际上在他们的文档中做了一个声明 (https://developer.apple.com/documentation/usernotifications/unnotificationattachment)

Apple 文档 UNNotificationAttachment:

... The system validates attachments before displaying the associated notification. ... Once validated, attached files are MOVED into the attachment data store so that they can be accessed by all of the appropriate processes. Attachments located inside an app’s bundle are copied instead of moved.

因此,上面的答案是先将附件(图像)复制到一个临时位置,然后再添加为附件,这似乎是预期的解决方案。

In Swift 5. 下面的代码对我有用。希望这对某人有所帮助。

let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
            
let imageURL = URL(fileURLWithPath: paths.first!).appendingPathComponent("\(fileName).jpg")
let image = UIImage(contentsOfFile: imageURL.path)
let imageData = image?.pngData()
            
if let unwrappedImageData = imageData, let attachement = try? UNNotificationAttachment(data: unwrappedImageData, options: nil) {
    content.attachments = [ attachement ]
}