iOS 10 Rich Media Push Notification (Media Attachment) in Objective-C

iOS 10 Rich Media Push Notification (Media Attachment) in Objective-C

your code is ok, it just expects a different push notification data format:

Try replacing this part:

// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default',
'mutable-content' => 1,
'category'=> "pusher"
$body['data'] = array(
'mediaUrl' => "",
'mediaType' => "jpg"


$body = array(
'aps' => array(
'alert' => 'Rich notification',
'sound' => 'default',
'mutable-content' => 1
'mediaUrl' => '',
'mediaType' => 'image'

Please note, that image should be accessible via https://

How can I add media attachments to my push notifications in an iOS 10 app?

You're most of the way there. The way you're going to send the attachment is usually as a URL in your payload. However, if you wanted to hard-code the attachment, like your code does, I think it would work, but I think you missed one critical component. I think the service extension does not have access to the main bundle or its resources. If you added a resource to the service extension and tried to load that (using something like [NSBundle bundleForClass:[NotificationService class]]), I suspect it would work.

However, if you send the URL as part of the payload, then you're going to load the image from that URL and not the bundle anyway. In that case, I'm pretty sure you also have to use startAccessingSecurityScopedResource on NSURL (along with stopAccessingSecurityScopedResource).

Hope that helps!

IOS Rich notification didReceiveNotificationRequest is not fired

You are downloading the image in background thread which is causing the issue in Rich Push Notification case. If you want you can try with this framework

Also Add "content-available":1 in your aps

OR you can try downloading like this,

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent *))contentHandler {

self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];

self.bestAttemptContent.title = [NSString stringWithFormat:@"%@",request.content.title];
self.bestAttemptContent.body = [NSString stringWithFormat:@"%@",request.content.body];

NSString *attachmentUrlString = [NSString stringWithFormat:@"%@",[request.content.userInfo valueForKey:@"thumbnail_image"]];

if (![attachmentUrlString isKindOfClass:[NSString class]]) {
[self failEarly];

NSURL *url = [NSURL URLWithString:attachmentUrlString];
if (!url) {
[self failEarly];

NSData *data = [NSData dataWithContentsOfURL:url];
if (!data) {
[self failEarly];

NSString *identifierName = [self getIdentifierName:attachmentUrlString];
NSString *tmpSubFolderName = [[NSProcessInfo processInfo] globallyUniqueString];

self.bestAttemptContent.attachments = [NSArray arrayWithObject:[self create:identifierName andData:data withOptions:nil andTmpFolderName:tmpSubFolderName]] ;


-(void)failEarly {

-(NSString *)getIdentifierName:(NSString *)fileURL
NSString *identifierName = @"image.jpg";

if (fileURL) {
identifierName = [NSString stringWithFormat:@"file.%@",fileURL.lastPathComponent];

return identifierName;

-(UNNotificationAttachment *)create:(NSString *)identifier andData:(NSData *)data withOptions:(NSDictionary *)options andTmpFolderName:(NSString *)tmpSubFolderName {

NSString *fileURLPath = NSTemporaryDirectory();
NSString *tmpSubFolderURL = [fileURLPath stringByAppendingPathComponent:tmpSubFolderName];
NSError *error;
[[NSFileManager defaultManager] createDirectoryAtPath:tmpSubFolderURL withIntermediateDirectories:TRUE attributes:nil error:&error];
if(!error) {
NSString *fileURL = [tmpSubFolderURL stringByAppendingPathComponent:identifier];
[data writeToFile:fileURL atomically:YES];
UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:identifier URL:[NSURL fileURLWithPath:fileURL] options:options error:&error];
return attachment;
return nil;

- (void)serviceExtensionTimeWillExpire {

Related Topics

Leave a reply