Learn & Master ⚔️ iOS Remote Push Notifications in 10 Minutes

Sebastian Boldt
Sep 30, 2018 · 9 min read

Remote Push notifications enable developers to present information to their users outside the app and to redirect them to the app if necessary. Important events will arrive in the form of badges, sounds or banners. But be careful here, too many push notifications may lower the retention and deter your users. When and how push notifications are displayed should be well considered, inflationary and unimportant notifications can mean death for a good app.

In the last iOS versions the range of functions around Push Notifications has grown enormously. It is now possible to define your own actions, to manipulate the content of the notifications before displaying them and to present them in a self-created interface.

If you want to know how these Push features work and what exactly you need to integrate them into your app, then you’ve come to the right place. I will show you the basics of this technology in less than 10 minutes.

What you need to master this tutorial:

What you’re gonna learn:

  • How the Notification System Works

How do Remote Push Notifications work?

I have created the following diagram, to give you an idea of the structure and the interactions of the different stations. I will explain the individual steps and explain them in more detail with the help of code examples.

1. Register App Push Notifications

First, the App must obtain a token from the APNS
(Apple Push Notification Service)

The APNS is a service provided by Apple that takes care of the security and integrity of the data.

The request for the app-token to the APNS, i.e. the token that uniquely identifies your app, is made from the app using the UNUserNotificationCenter class. In order for the app to be able to receive push notifications at all, the switch for push notifications must be activated in the capability settings.

This results in the App Id being updated for Push Notifications and a new Provisioning Profile being created as long as automatic-signing is activated.
In the case of manual administration, the provisioning profile would have to be updated in this case.

The request can now be made to the APNS.

As I already said, for this the class UNUserNotificationCenter can be used.
As you can see, you can pass different options to this method. Currently, the badge alert and sound options are sufficient for us. If the user agrees, the app should request the app token via registerForRemoteNotifications.

After the registration is completed the app receives a token. This token is volatile and should not be cached in the app. The token is only valid as long as the user does not reinstall the app or restore the device. The Token will be provided through a different method which will be described in the next section.

Further Options

The user is not initially asked whether he wants to receive the notifications, they end up in the Notification Center by default and can be accepted from there.

In order to allow critical alerts, a special entitlement must be applied for at Apple.

This flag must also be passed so that the Push Notification also appears in the Carplay Hud.

2. Receive Token from APNS

After the request via registerForRemoteNotifications was successful, the function application:didRegisterForRemoteNotificationsWithDeviceToken is called in the AppDelegate. Unfortunately, the token will be provided in the form of a Data-Object. It must be converted into a hex string like so:

3. Update Backend Service with Information about Device/User

In order for your private server to know which devices have registered for which push notifications, it needs to know that this has been approved.
In the course of this article I will not go into this step any further because it can be implemented differently from system to system.
However, it is not absolutely necessary to write your own backend.
Services from Google and Amazon offer everything you need to get started.

In this tutorial we will use the PushNotifications program to represent our server. A small desktop tool that communicates with the APNS.
Download: https://github.com/onmyway133/PushNotifications

4. Provider sends Request to APNS

Only requests that are authenticated with an authentication-token may be sent to the APNS. This ensures that only the originator of the authentication-token has the possibility to send notifications to his users. This token can be used for all your apps in all forms (Development, Production).

To create one you need to go the the Apple Member Center and create one, give it a name and download it.
You should now have a file with the .p8 extension.

Now configure the Push Notification Application previously downloaded from GitHub. Open the App and select the .p8 file under Token Authentication. Enter the Token-Key, Team-Id, Bundle Identifier and the actual device token we printed out in didRegisterForRemoteNotifications. Press send and your device should receive an notification if the app is not open.

If you want your notifications to be displayed when the app is open, you need to add yourself as a delegate to the UNUserNotificationCenter and implement the delegate method userNotificationCenter:center:willPresent:withCompletionhandler: and pass the options to the completion handler like this.

5. APNS sending Push Notifications

The push notifications arrive in the form of JSON. The maximum size of this file is 4kb. If it exceeds the size, it will simply not be delivered.
A technique that helps here is the subsequent download of data on the device using a notification service extension which will be described in the next section.

The format of this JSON is partly given by Apple.
Here is an example for a possible configuration:

"aps" : {
"alert" : {
"title" : "Hello World",
"subtitle" : "This is awesome"
"body” : “Even more Content",
"thread_identifier": "Master-Thread"
"badge": 12,
"sound": "customSound.caf"
"custom-data" : {
"custom-element": "custom-value"
  • aps — top element defined by apple

Apple combines all push notifications with the same identifier.
If no identifier is specified, all notifications are simply combined to a group.

  • custom-data — You custom json should be provided under the aps object

6. Responding to Interaction

After the push notification has arrived on the user’s device, he can interact with it. The easiest way to do this is to tap it. Touching the Notification leads the user to the app. A delegate function of the UNNotificationCenter is responsible for the administration of this interaction.

The response.identifier can be used to find out to what extent the user interacted with the notification. The default is UNNotificationDefaultActionIdentifier

Silent Notifications

Not all notifications from the server should necessarily make the user aware of something, but simply update content in the app, for example.
Silent notifications can be used for this purpose.
For these to work, remote notifications must be activated in the Background Mode Capabilites. Some new delegate methods must be implemented depending on which state the app has and the flag content-available set to 1 in json. If you are interested in the topic silent notifications please consult the documentation to it.

7. Custom Actions

It is possible to define different categories within the app. These categories consist of a unique identifier and a set of actions. After they have been defined they only have to be added to the UNUserNotificationCenter.

Each action is represented in the UI by a button below the notification. The category identifier is simply set as subelement in the aps object of the json.

"aps" : {
"alert" : {
"title" : "Hello Push",
"category": "custom"

If the same category is found on the device, the first two actions are displayed in the UI.

8. Payload Modification

From time to time, the content of a push notification may be formatted or enriched with additional data. A notification service extension can be used for this purpose. This acts as a mediator between the User Interface and the APNS. Like all other iOS extensions, such an extension can simply be added to the app in the form of another target.

After the target has been created, a new file named NotificationService is located in the Project. The function signatures and comments already show how this extension works. On average, the system allows you 30 seconds to perform any operations in the didReceive function. If the time limit is exceeded, the serviceExtensionTimeWillExpire function informs you of this.
You can use this function to encrypt data, load images or do some calculations before the actual notification gets displayed.

As with any other iOS extension it is also possible to share data with the parent app.

9. Custom UI

Not only the data can be modified by an extension but also the UI.
A notification content extension is used for this purpose.
This is created in the same way as a service extension. The Target will contain a new ViewConroller, a plist and a Storyboard which can be modified as you wish.

When the custom UI is displayed depends on the linked category, which we have already used above to define custom actions. The name of the category can be changed via the target or directly via the plist file of the new extension.

Basically, everything can be realized here that is also done in a normal App-ViewController. You can add MapViews, use Autolayout etc.

Possible features:
Text-Input, dynamic Actions, Videos, Pictures, Custom Input Views

It`s a wrap 🌯

I think this Article is a good and simple introduction into the World of iOS-Push Notifications. Of course, the framework can do even more, but I think that the basis for understanding more complex functions has been laid.

If the article has helped you and you want me to continue writing similar articles, you are welcome to support me with a small donation

🤜🏾 🤛

Congratulation, you learned the basics of Push Notifications.
Happy Coding 🎉

Feel free to add me on github, twitter, linkedin or xing if you have any questions. If you like electronic music you can also listen to my Tracks on SoundCloud ;)

iOS App Development

Stories and technical tips about building apps for iOS…

iOS App Development

Stories and technical tips about building apps for iOS, Apple Watch, and iPad/iPhone

Sebastian Boldt

Written by

Creative Head, iOS Developer @ Immowelt, DJ/Producer from Hamburg. Creator of HabitBe, a weekly Habit Tracker written in SwiftUI. https://www.sebastianboldt.com

iOS App Development

Stories and technical tips about building apps for iOS, Apple Watch, and iPad/iPhone