【问题标题】:UNNotificationAttachment failing to attach imageUNNotificationAttachment 无法附加图片
【发布时间】:2017-12-26 20:48:48
【问题描述】:

因此,以下代码用于从图像的本地存储 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}

【问题讨论】:

  • catch 语句中抛出了什么错误?将其添加到问题中。
  • @RoboticCat 感谢您的回复。错误显示Invalid attachment file URL。我检查了 URL,它是有效的,并且能够使用终端查看存储在该位置的图像。

标签: ios swift usernotifications unnotificationserviceextension unnotificationattachment


【解决方案1】:

我发现了它背后的真正问题。在苹果文档中写到该 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]

【讨论】:

  • 这似乎奏效了,生成了网址,但仍然出现错误:Error occurred adding notification Invalid attachment file URL 所以愚蠢我在图像中投入了多少时间以显示在该死的通知上。
  • 对于尝试此解决方案的每个人,首先它是有效的。确保您调用 contentHandler 一次。不要将此代码放在 Xcode 生成的现有代码之下。否则,将附件添加到 bestAttemptContent 将不起作用。 :)
  • 很好的答案,但没有理由在 NSTemporaryDirectory() 中创建文件夹。有时在临时目录中创建文件夹在通知服务中失败,所以不要这样做,这个答案是黄金。
【解决方案2】:

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

"Invalid attachment file URL"

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

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

【讨论】:

  • 这应该是公认的答案,很好地破坏了这种精神错乱@vojta!
  • 是的,这肯定是一种未记录的行为。这也是我面临的。这是一种耻辱,但确实如此。 " UNNotificationAttachment 初始化过程正在删除给定 URL 的文件" !!!!!!!
  • @vojta 你能确认I made a standalone copy of an image for each attachment 的意思吗?你是从网上下载两张图片还是用 URL 的位置做一些不同的事情?
  • @SuryaKantSharma nope,声明 I made a standalone copy of an image for each attachment 我的意思是我已经使用 NSFileManager 为每个 UNNotificationAttachment 创建了本地图像文件。希望对你有帮助
  • 我也遇到了这个问题。在我的情况下,缓存的图像文件不包含导致错误的文件扩展名(如.png)。
【解决方案3】:

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

UNNotificationAttachment 的 Apple 文档:

... 系统会在显示相关通知之前验证附件。 ... 验证后,附件将被移动到附件数据存储中,以便所有适当的人都可以访问它们 过程。复制位于应用程序包内的附件 而不是移动。

因此,在添加为附件之前先将附件(图像)复制到临时位置的上述答案似乎是预期的解决方案。

【讨论】:

    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2018-08-08
      • 2016-02-08
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2021-03-27
      • 2013-12-20
      • 1970-01-01
      相关资源
      最近更新 更多