Rich notifications
Notification Service Extension Creating
Create a Notification Service Extension first. This extension downloads the content that will be shown to the player. In order to create the extension add a new target to your project (File >> New >> Target) and create Notification Service Extension.

Make sure you embed your new extension in your app:

Notification Service Extension has a separate Apple App ID and Provisioning profile.
Note that notification extension has its own Bundle Id (ex: com.gow.test.NotificationService) as well as its own Apple App ID and Provisioning profile which has to be setup in Apple Developer Portal separately.
Notification Service Extension Code
The following code downloads the attachment and calls the notification content handler. Just Copy & Paste it to your extension.
#import "NotificationService.h" @interface NotificationService () @property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver); @property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent; @end @implementation NotificationService - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { NSLog(@"NotificationService"); self.contentHandler = contentHandler; self.bestAttemptContent = [request.content mutableCopy]; NSString *attachmentUrlString = [request.content.userInfo objectForKey:@"image"]; if (![attachmentUrlString isKindOfClass:[NSString class]]) return; NSURL *url = [NSURL URLWithString:attachmentUrlString]; if (!url) return; [[[NSURLSession sharedSession] downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (!error) { NSString *tempDict = NSTemporaryDirectory(); NSString *attachmentID = [[[NSUUID UUID] UUIDString] stringByAppendingString:[response.URL.absoluteString lastPathComponent]]; if(response.suggestedFilename) attachmentID = [[[NSUUID UUID] UUIDString] stringByAppendingString:response.suggestedFilename]; NSString *tempFilePath = [tempDict stringByAppendingPathComponent:attachmentID]; if ([[NSFileManager defaultManager] moveItemAtPath:location.path toPath:tempFilePath error:&error]) { UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:attachmentID URL:[NSURL fileURLWithPath:tempFilePath] options:nil error:&error]; if (!attachment) { NSLog(@"Create attachment error: %@", error); } else { _bestAttemptContent.attachments = [_bestAttemptContent.attachments arrayByAddingObject:attachment]; } } else { NSLog(@"Move file error: %@", error); } } else { NSLog(@"Download file error: %@", error); } [[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.contentHandler(self.bestAttemptContent); }]; }] resume]; } - (void)serviceExtensionTimeWillExpire { self.contentHandler(self.bestAttemptContent); } @end
Non-secure attachment URL's Allowing
Notification Service Extension is a separate binary and has its own Info.plist file. Starting with iOS 9 release to download the content from non-https URL (ex: http://) you have to add App Transport Security Settings with Allow Arbitrary Loads flag set to YES to extension's Info.plist file.

Rich Notification Sending
In order to send a rich notification just specify the image in the push notification settings.