To implement rich notifications you will have to create a new Notification Service Target that will be responsible for downloading the media of the notification and attach it to the notification object.
Copy override func didReceive ( _ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) - > Void ) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
if let mediaUrl = request.content.userInfo[ "media_url" ] as? String, let fileUrl = URL ( string: mediaUrl ) {
downloadMedia(fileUrl: fileUrl, request: request, bestAttemptContent: bestAttemptContent ) {
contentHandler(bestAttemptContent )
}
} else {
contentHandler(bestAttemptContent )
}
}
}
func downloadMedia ( fileUrl: URL, request: UNNotificationRequest, bestAttemptContent: UNMutableNotificationContent, completion: @escaping () - > Void ) {
let task = URLSession.shared.downloadTask ( with: fileUrl ) { (location, _, _ ) in
if let location = location {
let tmpDirectory = NSTemporaryDirectory ()
let tmpFile = "file://" .appending ( tmpDirectory ) .appending ( fileUrl.lastPathComponent )
let tmpUrl = URL ( string: tmpFile ) !
do {
try FileManager.default.moveItem ( at: location, to: tmpUrl )
var options: [String: String]? = nil
if let type = request.content.userInfo[ "media_type" ] as? String {
options = [String: String] ()
options?[UNNotificationAttachmentOptionsTypeHintKey] = type
}
if let attachment = try? UNNotificationAttachment ( identifier: "media." + fileUrl.pathExtension, url: tmpUrl, options: options ) {
bestAttemptContent.attachments = [attachment]
}
completion ()
} catch {
completion ()
}
}
}
task.resume ()
}
override func serviceExtensionTimeWillExpire () {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent )
}
}
With this code, we download the attachment, if exists, and move it to a temporary directory. Then we add it to our notification with
Copy if let attachment = try? UNNotificationAttachment ( identifier: "media." + fileUrl.pathExtension, url: tmpUrl, options: options ) {
bestAttemptContent.attachments = [attachment]
}