{"_id":"57d6c4294340330e00953ce6","parentDoc":null,"project":"54aa7f773b56130b0056c86e","githubsync":"","user":"57bc3654b9c7f0220009c77b","version":{"_id":"55781fe25129590d003ff4f7","project":"54aa7f773b56130b0056c86e","forked_from":"54aa7f773b56130b0056c871","__v":6,"createdAt":"2015-06-10T11:30:42.700Z","releaseDate":"2015-06-10T11:30:42.700Z","categories":["55781fe35129590d003ff4f8","55781fe35129590d003ff4f9","55781fe35129590d003ff4fa","55781fe35129590d003ff4fb","55781fe35129590d003ff4fc","55781fe35129590d003ff4fd","55781fe35129590d003ff4fe","564bbc7e8841060d00abb2ee","565b66c446118c0d00dcb0bb","56898269f8dc340d00308c13","582318b23b961a0f009516a1","594a848c9f4771001a43c959"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"Developers","version_clean":"2.0.0","version":"2.0"},"__v":2,"category":{"_id":"55781fe35129590d003ff4fb","version":"55781fe25129590d003ff4f7","__v":11,"pages":["55781fe45129590d003ff517","55781fe45129590d003ff518","55781fe45129590d003ff519","55781fe45129590d003ff51a","55781fe45129590d003ff51b","55781fe45129590d003ff51c","55781fe45129590d003ff51d","55781fe45129590d003ff51e","55781fe45129590d003ff51f","55781fe45129590d003ff520","55781fe45129590d003ff521","55781fe45129590d003ff522","5579ab5fc7fb3f2100096fad","55f7de1660cc850d008a7a22","55f7e1fbe32e9b0d00a2d4d0","561f72bacec1a50d00979598","561f764f61c0521700acc428","563337539c607719001b85dd","564318f1f49bfa0d002f5566","564f03454f000617007bd670","565ee80a23fd5f0d00a129f9","56793cd73473bc0d008e141b"],"project":"54aa7f773b56130b0056c86e","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-01-05T12:43:51.897Z","from_sync":false,"order":3,"slug":"ios-sdk","title":"iOS SDK"},"updates":["5afa88d3a816770003116889"],"next":{"pages":[],"description":""},"createdAt":"2016-09-12T15:05:13.467Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":20,"body":"iOS 10 now allows Developers to modify the push payload before it is presented. To do that you need to create an new Application Extension called \"Notification Service Extension\".\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"1. Application Extension - Notification Service Extension\"\n}\n[/block]\nTo create a new application extension select in xCode *File -> New -> Target...* and select Notification Service Extension.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/ce5c217-2018-07-13_05.36.41_pm.png\",\n        \"2018-07-13 05.36.41 pm.png\",\n        1466,\n        1056,\n        \"#ececeb\"\n      ],\n      \"caption\": \"Screen Shot that you guys have added is for Notification Content. But for Rich push we need to add Notification Service Extension.\"\n    }\n  ]\n}\n[/block]\nThe App Extension must have it's own App ID and Provisioning Profile set up in the Apple Developer Center.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"2. Configuring the Notification Service Extension\"\n}\n[/block]\nAfter creating the new App Extension you should have a new header file, objective-c file and plist. This is the default code that will work with Pulsate.\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"#import \\\"NotificationService.h\\\"\\n\\nstatic NSString* const PulsateAttachmentUrl = :::at:::\\\"au\\\";\\nstatic NSString* const PulsateAttachmentType = @\\\"at\\\";\\n\\n@interface NotificationService ()\\n\\n@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);\\n@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;\\n@property (nonatomic, strong) UNMutableNotificationContent *notificationContent;\\n\\n@end\\n\\n@implementation NotificationService\\n\\n- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {\\n    self.contentHandler = contentHandler;\\n    self.bestAttemptContent = [request.content mutableCopy];\\n    self.notificationContent = [request.content mutableCopy];\\n    \\n    if (request.content.userInfo == nil) {\\n        [self defaultPushHandler];\\n        return;\\n    }\\n    \\n    if (request.content.userInfo[PulsateAttachmentType] == nil || request.content.userInfo[PulsateAttachmentUrl] == nil) {\\n        [self defaultPushHandler];\\n        return;\\n    }\\n    \\n    NSString* pulsateAttachment = request.content.userInfo[PulsateAttachmentUrl];\\n    NSString* pulsateAttachmentType = request.content.userInfo[PulsateAttachmentType];\\n    NSString *suffix = [@\\\".\\\" stringByAppendingString:pulsateAttachmentType];\\n    NSURL *pulsateAttachmentUrl = [NSURL URLWithString:pulsateAttachment];\\n    \\n    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];\\n    [[session downloadTaskWithURL:pulsateAttachmentUrl\\n                completionHandler:^(NSURL *url, NSURLResponse *response, NSError *error) {\\n                    if (error != nil) {\\n                        [self defaultPushHandler];\\n                        return;\\n                    } else {\\n                        NSFileManager *fileManager = [NSFileManager defaultManager];\\n                        NSURL *typedUrl = [NSURL fileURLWithPath:[url.path stringByAppendingString:suffix]];\\n                        [fileManager moveItemAtURL:url toURL:typedUrl error:&error];\\n                        \\n                        NSError *error = nil;\\n                        UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@\\\"\\\" URL:typedUrl options:nil error:&error];\\n                        if (attachment == nil) {\\n                            [self defaultPushHandler];\\n                            return;\\n                        }\\n                        self.bestAttemptContent.attachments = [NSArray arrayWithObjects:attachment, nil] ;\\n                        self.contentHandler(self.bestAttemptContent);\\n                    }\\n                }] resume];\\n}\\n\\n- (void)serviceExtensionTimeWillExpire {\\n    // Called just before the extension will be terminated by the system.\\n    // Use this as an opportunity to deliver your \\\"best attempt\\\" at modified content, otherwise the original push payload will be used.\\n    self.contentHandler(self.bestAttemptContent);\\n}\\n\\n- (void)defaultPushHandler {\\n    self.contentHandler(self.bestAttemptContent);\\n}\\n\\n@end\\n\",\n      \"language\": \"objectivec\"\n    }\n  ]\n}\n[/block]","excerpt":"","slug":"ios-10-rich-notification","type":"basic","title":"iOS 10 Rich Notification"}

iOS 10 Rich Notification


iOS 10 now allows Developers to modify the push payload before it is presented. To do that you need to create an new Application Extension called "Notification Service Extension". [block:api-header] { "type": "basic", "title": "1. Application Extension - Notification Service Extension" } [/block] To create a new application extension select in xCode *File -> New -> Target...* and select Notification Service Extension. [block:image] { "images": [ { "image": [ "https://files.readme.io/ce5c217-2018-07-13_05.36.41_pm.png", "2018-07-13 05.36.41 pm.png", 1466, 1056, "#ececeb" ], "caption": "Screen Shot that you guys have added is for Notification Content. But for Rich push we need to add Notification Service Extension." } ] } [/block] The App Extension must have it's own App ID and Provisioning Profile set up in the Apple Developer Center. [block:api-header] { "type": "basic", "title": "2. Configuring the Notification Service Extension" } [/block] After creating the new App Extension you should have a new header file, objective-c file and plist. This is the default code that will work with Pulsate. [block:code] { "codes": [ { "code": "#import \"NotificationService.h\"\n\nstatic NSString* const PulsateAttachmentUrl = @\"au\";\nstatic NSString* const PulsateAttachmentType = @\"at\";\n\n@interface NotificationService ()\n\n@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);\n@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;\n@property (nonatomic, strong) UNMutableNotificationContent *notificationContent;\n\n@end\n\n@implementation NotificationService\n\n- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {\n self.contentHandler = contentHandler;\n self.bestAttemptContent = [request.content mutableCopy];\n self.notificationContent = [request.content mutableCopy];\n \n if (request.content.userInfo == nil) {\n [self defaultPushHandler];\n return;\n }\n \n if (request.content.userInfo[PulsateAttachmentType] == nil || request.content.userInfo[PulsateAttachmentUrl] == nil) {\n [self defaultPushHandler];\n return;\n }\n \n NSString* pulsateAttachment = request.content.userInfo[PulsateAttachmentUrl];\n NSString* pulsateAttachmentType = request.content.userInfo[PulsateAttachmentType];\n NSString *suffix = [@\".\" stringByAppendingString:pulsateAttachmentType];\n NSURL *pulsateAttachmentUrl = [NSURL URLWithString:pulsateAttachment];\n \n NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];\n [[session downloadTaskWithURL:pulsateAttachmentUrl\n completionHandler:^(NSURL *url, NSURLResponse *response, NSError *error) {\n if (error != nil) {\n [self defaultPushHandler];\n return;\n } else {\n NSFileManager *fileManager = [NSFileManager defaultManager];\n NSURL *typedUrl = [NSURL fileURLWithPath:[url.path stringByAppendingString:suffix]];\n [fileManager moveItemAtURL:url toURL:typedUrl error:&error];\n \n NSError *error = nil;\n UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@\"\" URL:typedUrl options:nil error:&error];\n if (attachment == nil) {\n [self defaultPushHandler];\n return;\n }\n self.bestAttemptContent.attachments = [NSArray arrayWithObjects:attachment, nil] ;\n self.contentHandler(self.bestAttemptContent);\n }\n }] resume];\n}\n\n- (void)serviceExtensionTimeWillExpire {\n // Called just before the extension will be terminated by the system.\n // Use this as an opportunity to deliver your \"best attempt\" at modified content, otherwise the original push payload will be used.\n self.contentHandler(self.bestAttemptContent);\n}\n\n- (void)defaultPushHandler {\n self.contentHandler(self.bestAttemptContent);\n}\n\n@end\n", "language": "objectivec" } ] } [/block]