Codementor Events

Handle Incoming Notifications in iOS

Published Apr 23, 2020
Handle Incoming Notifications in iOS

How can I do something with the incoming Push notifications in iOS?

So let’s, first of all, explain the needs. In my particular case, I need to make an HTTP call (more specifically publish a message to a PubNub channel) every time I receive a notification in my app. It’s to let my server know the second a notification is received.
This is possible in iOS as it is in Android. In iOS, it can be done through the Notification Service Extension target, which we can add to our project through File > New > Target.

1*54JHhNFxm4NVLVjX_EHObA.png

Notification Service Extensions

The main purpose of the Notification Service Extension in iOS is to be able to change or enrich the notification with further information before it gets displayed by the operating system.
Even downloading content in response to the notification or making HTTP requests to a server is allowed.
Note that Notification Service Extensions are available only from iOS 10 and up, and you’ll need to do this implementation with XCode 8 or up.

Extension lifecycle

Once you have configured your app with a notification service extension, the following process will take place for each notification:

  • App receives notification.
  • System creates an instance of your extension class and launches it in the background.
  • Your extension performs content edits and/or downloads some content.
  • If your extension takes too long to perform its work, it will be notified and immediately terminated.
  • Notification is displayed to the user.

As you can see, when using a notification service extension, you only have a limited amount of time to perform the necessary work. This is controlled by the operating system just as for other background tasks in iOS. If your extension is taking too long, or any other exception happens while the extension is being executed, then it will be stopped by the system, and the notification will be delivered as if you had no extension at all.

Code

After adding this target to your project, there’ll be three files created in it.

  • NotificationService.h
  • NotificationService.m
  • Info.plist

If you’re using Swift, you’ll have just two files: NotificationService.swift and Info.plist.

So the code goes in NotificationService[.m]. The class extends UNNotificationServiceExtension, which is imported from <UserNotifications/UserNotifications.h>.

The class has to implement the following two methods:

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
   self.contentHandler = contentHandler;
   self.bestAttemptContent = [request.content mutableCopy];
   // change bestAttemptContent here ...
   self.contentHandler(self.bestAttemptContent);
}
- (void)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.
   self.contentHandler(self.bestAttemptContent);
}

The first one obviously is the one needed to do all the jobs you need it to perform.

Correctly setting up the extension on your project

1*BvjV3L5BhRB3Vly404agnw.png

Be sure to have these capabilities added to your targets. Both the app target and the extension need to have push notifications enabled. Moreover, on the app target, also add Background Modes.

1*gryXazi80T-CQo97oszBWg.png

Extension restrictions

It’s important to know the conditions under which the extension will operate when using a notification service extension.

Firstly, your extension will only be launched for notifications that are configured to show onscreen alerts to the user. This means that any silent notifications will not trigger your extension.

Moreover, the incoming notification must be marked as having mutable content. To do so, add the key mutable-content with value 1 to the aps dictionary.
Another thing handy to know is how to share information between the app and the extension. As you can see from the image above, I have added the App Groups capability to the Extensions. The same has been done for the app. Defined app groups must have the same name (e.g., group.com.clubsmade.eventsapp). This makes it easy to share information using NSUserDefaults as follows:

NSUserDefaults *myDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.clubsmade.eventsapp"];
[myDefaults setObject:channelName forKey:@"channelName"];
[myDefaults synchronize];

In the above code snipped, I’m saving a channel name into my shared instance of User Defaults. You can notice that the NSUserDefaults instance has been created with a suite name.

The channel name I’m saving in my user defaults will be used from my extension to publish some messages to the PubNub channel.

To then read this information from User Defaults, use the following snippet:

NSUserDefaults *defaultUserPreferences = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.clubsmade.eventsapp"];
NSString *channelName = [defaultUserPreferences stringForKey:@"channelName"];

It’s just that easy.

Conclusion

Through the new UNNotificationServiceExtension class in iOS 10, it’s very simple for you to implement a notification service extension for your own applications. Whatever your use case, these APIs allow you to easily modify the content of a notification before it’s shown to the user or to perform other operations in a limited time frame.

Discover and read more posts from Eni Sinanaj
get started