Rich Notifications

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.

In Xcode go to File -> New -> Target and choose Notification Service Extension

Keep in mind that notifications don't have much time to download the media attached, if the download doesn't finish in a short period of time the notification will be delivered without the media.

To handle MPush attachments add this your NotificationService should look like this:

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

if let attachment = try? UNNotificationAttachment(identifier: "media." + fileUrl.pathExtension, url: tmpUrl, options: options) {
bestAttemptContent.attachments = [attachment]
}