Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UNNotificationAttachment failing to attach image

So the following code is being used to attach an image from local storage url of an image. I check in Terminal to see if the image is stored and it does store the image without any issues. So ruling out any issues with the url itself.

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

Other code that goes with the creation of UserNotification works fine as it triggers at the correct specified time.

The code always goes to the catch block. Can anybody please point me to the mistake if there is any in the implementation. Please help. Thank you.

Edit: with print(error.localizedDescription) error message is Invalid attachment file URL.

Edit2 : with print(error) error message is Error Domain=UNErrorDomain Code=100 "Invalid attachment file URL" UserInfo={NSLocalizedDescription=Invalid attachment file URL}

like image 846
as diu Avatar asked Jul 20 '17 23:07

as diu


2 Answers

I have found the real issue behind it. In apple documentation it is written that the url should be a file url and because of which you might be facing issue.

To solve this I have added image to temporary directory and then added to UNNotificationAttachment .

Please find the code below. (For my use case I was getting an 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
    }
}

data in the argument of this function is Data of image . Below is how did I call this method.

let imageData = NSData(contentsOf: url)
guard let attachment = UNNotificationAttachment.create(imageFileIdentifier: "img.jpeg", data: imageData!, options: nil) else { return  }
            bestAttemptContent?.attachments = [attachment]
like image 136
Mridul Gupta Avatar answered Oct 18 '22 12:10

Mridul Gupta


I also found important and quite weird behaviour of initialization of UNNotificationAttachment object. It was happening to me that I was getting error:

"Invalid attachment file URL"

But it was not happening always. It was happening in case when I used for some notifications same image for attachment. When I made a standalone copy of image for each attachment, it never happened. Then I checked directory when images should be copied ( because I wanted to clean it up ), but I was surprised that there were no images.

It seems that UNNotificationAttachment initialization process is deleting files at given URLs. So when you try to reuse some images, they can be deleted ( probably asynchronously, because I was checking existence of that images and it always returned me true - that file exists ). But UNNotificationAttachment ended up with error you can see above. In my opinion only logic explanation of this error is that file at given URL is deleted during the process of UNNotificationAttachment initialization.

like image 41
Vojta Avatar answered Oct 18 '22 13:10

Vojta