UNNotificationAttachment не удалось прикрепить изображение

Поэтому следующий код используется для прикрепления изображения из локального 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}

4 ответа

Решение

Я нашел реальную проблему за этим. В документации Apple написано, что URL должен быть URL файла, и из-за чего у вас могут возникнуть проблемы.

Чтобы решить эту проблему, я добавил изображение во временную директорию, а затем добавил в UNNotificationAttachment,

Пожалуйста, найдите код ниже. [В моем случае я получал URL изображения]

 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-адресам. Поэтому, когда вы пытаетесь повторно использовать некоторые изображения, они могут быть удалены (возможно, асинхронно, потому что я проверял существование этих изображений, и он всегда возвращал мне истину - этот файл существует). Но UNNotificationAttachment закончился с ошибкой, которую вы можете увидеть выше. На мой взгляд, логичным объяснением этой ошибки является то, что файл по заданному URL-адресу удаляется в процессе инициализации UNNotificationAttachment.

Apple фактически делает заявление в своей документации (https://developer.apple.com/documentation/usernotifications/unnotificationattachment)

Apple Docs для приложения UNNotificationAttachment:

... Система проверяет вложения перед отображением соответствующего уведомления.... После проверки вложенные файлы ПЕРЕМЕЩАЮТСЯ в хранилище данных вложений, чтобы к ним могли получить доступ все соответствующие процессы. Вложения, расположенные внутри пакета приложения, копируются, а не перемещаются.

Итак, приведенные выше ответы с копированием вложения (изображения) сначала во временное место перед добавлением в качестве вложения кажутся ожидаемым решением.

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