16

Apple introduce new extension names "UNNotificationServiceExtension", but how to launch it from push notification ?

I read that service extension provide end to end encryption for payload.

Which key is required to set payload of push notification ?

How to identify payload and how to launch service extension from push notification ?

Stanislav Mayorov
  • 4,298
  • 5
  • 21
  • 44
technerd
  • 14,144
  • 10
  • 61
  • 92
  • 1
    Watch the videos. https://developer.apple.com/videos/play/wwdc2016/707/ https://developer.apple.com/videos/play/wwdc2016/708/ – matt Oct 14 '16 at 12:23

2 Answers2

47

Let me take it step by step.

UNNotificationServiceExtension - What it is?

UNNotificationServiceExtension is an App Extenstion target that you bundle along with your app aiming to modify the push notifications as and when they are delivered to the device before rendering it to the user. You can change the title, subtitle, body and additionally add attachments to the push notification by either downloading it or using one bundled in the app.

How to create

Go to File -> New -> Target -> Notification Service Extension and fill in the details

Which key is required to set payload of push notification?

You need to set the mutable-content flag to 1 to trigger the service extension. Also, if the content-available is set to 1, the service extension will not work. So either don't set it or set it to 0. (Edit: This is not applicable. You can set or unset content-available flag)

How to identify payload and how to launch service extension from push notification?

Build the extension and then build and run your app. Send a push notification with the mutable-content set to 1.

Code

UNNotificationService exposes two functions:

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

- (void)serviceExtensionTimeWillExpire;

The first function is triggered when the push notification is received on the device and before it is presented to the user. You code inside the function has the opportunity to modify the content of the push notification inside this function.

You do this by modifying the bestAttemptContent property of your extension which is an instance of UNNotificationContent and has properties: title, subtitle, body, attachments etc.

The original payload of the remote notification is delivered via request.content property of function parameter request.

Finally you dispatch your bestAttemptContent using the contentHandler:

self.contentHandler(self.bestAttemptContent); 

You have limited time to do your stuff in the first method. In case that time expires your second method is called with the best attempt your code had made thus far.

Sample Code

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request
               withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];

    // Modify the notification content here...
    self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];
    self.contentHandler(self.bestAttemptContent);
}

The above code appends [modified] to the original title in the PN payload.

Sample Payload

{
    "aps": {
        "alert": {
            "title": "Hello",
            "body": "body.."
        },
        "mutable-content":1,
        "sound": "default",
        "badge": 1,

    },
  "attachment-url": ""
}

Please note that the attachment-url key is a custom key for your own concerns and not recognised by iOS .

mickeymoon
  • 4,820
  • 5
  • 31
  • 56
  • 1
    To the point answer. Good Explanation. Specially for `You need to set the 'mutable-content' flag to 1 to trigger the service extension. Also, if the 'content-available' is set to 1, the service extension will not work.So either don't set it or set it to 0.` – technerd Oct 17 '16 at 09:55
  • Are you sure about point of "content-available" key? I use in my app and it works without problem. – Foriger Nov 02 '16 at 07:22
  • @Foriger I remember I had read it somewhere and also it was mentioned that it may not work with the content-available flag turned on. I tried looking up for the same again but couldn't find it. I'll update it if I find it. – mickeymoon Nov 02 '16 at 10:05
  • @mickeymoon can we trigger the service extension by local notification? – Vinu David Jose Dec 29 '16 at 11:36
  • @DashAndRest Yes it would work as long as you set the `mutable-content` flag – mickeymoon Jan 10 '17 at 09:12
  • 1
    Is it possible to call AppDelegate method from the service extension? – Dmitry May 01 '17 at 15:11
  • 1
    @Foriger Yes you are right about the `content-available` key. It works with that as well. I've updated the answer accordingly. – mickeymoon May 08 '17 at 14:14
  • 2
    @Dmitry No you cannot call UIApplication and thus not reach your app delegate, from the extension. – Jonny Dec 15 '17 at 07:19
  • @Jonny can I access user preferences in the Extension? And if yes how please? – FreedomOfSpeech Sep 07 '18 at 21:00
  • @mickeymoon can i get push data in this method if app is in background or removed from background ? – Jigar Tarsariya Oct 12 '18 at 10:26
  • @Jonny How to pass data from AppDelegate to the extension. Do you have any blog or tutorial? Please check my question here:- https://stackoverflow.com/q/54133966/1635315 – Kirti Nikam Jan 10 '19 at 17:42
  • 2
    Note that if you're using firebase cloud messaging the key is named "mutable_content" not "mutable-content" (underscore vs dash) – N S Jan 27 '19 at 19:02
  • @FreedomOfSpeech You can access user preferences by setting up App Groups for your app and extension. You need to read and write preferences to the app group's preferences, not the default ones. – mickeymoon Aug 22 '19 at 11:33
  • `Also, if the content-available is set to 1, the service extension will not work. So either don't set it or set it to 0. (Edit: This is not applicable. You can set or unset content-available flag)` That is false. You cannot add both flags `content-available` and `mutable-content` as that would simply not send the push notification at all (that's what happened with me). Also, check this from OneSignal: https://documentation.onesignal.com/docs/data-notifications#does-confirmed-deliveries-work-with-silent-push-notifications – Nino Bouchedid Sep 03 '20 at 12:04
  • 1
    @NinoBouchedid Got it, at the time of writing this wasn't a limitation, but I see the link mentions the problem. If you set the content-available flag, notification is sent as a silent notification and NSE is not triggered, but if you set the body, NSE is triggered and notification is shown. So, `content-available` cannot be used to send silent notification and trigger NSE as well, as OneSignal was hoping to use it to provide delivery ack. – mickeymoon Sep 06 '20 at 07:54
  • I tried every way. I put debug on - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent *contentToDeliver))contentHandler { } . I send push many times but it didn't call this method anyway. What i do wrong? – yasin89 Nov 10 '22 at 10:22
2

Notification service extension very useful in download content from notification data and display in notification like image and other content. you can also use notification service extension for execute some code when application is in background mode or in-active(killed).

Here is step by step guidelines of how to use notification service extension. And also you got the demo from from github.

Bera Bhavin
  • 673
  • 5
  • 10