iosswiftuiimageunnotificationserviceextensionunnotificationattachment

UNNotificationAttachment with UIImage or Remote URL


In my Notification Service Extension I am downloading an image from a URL to show as UNNotificationAttachment in a notification.

So I have this image as UIImage and don't see the need to write it in my app directory / group container on disc just to set up the notification.

Is there a good way create an UNNotificationAttachment with a UIImage ? (should be appliable to local and remote notifications)


Solution

    1. create directory in tmp folder
    2. write the NSData representation of the UIImage into the newly created directory
    3. create the UNNotificationAttachment with url to the file in tmp folder
    4. clean up tmp folder

    I wrote an extension on UINotificationAttachment

    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)
                let imageData = UIImage.pngData(image)
                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
        }
    }
    

    So to create UNUserNotificationRequest with UNUserNotificationAttachment from a UIImage you can simply do sth like this

    let identifier = ProcessInfo.processInfo.globallyUniqueString
    let content = UNMutableNotificationContent()
    content.title = "Hello"
    content.body = "World"
    if let attachment = UNNotificationAttachment.create(identifier: identifier, image: myImage, options: nil) {
        // where myImage is any UIImage
        content.attachments = [attachment] 
    }
    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 120.0, repeats: false)
    let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)
    UNUserNotificationCenter.current().add(request) { (error) in
        // handle error
    }
    

    This should work since UNNotificationAttachment will copy the image file to an own location.