iOS Remote Push Notifications with a Node.js backend
Posted on February 14, 2017 by Paul
In this tutorial I will show you how to get started with Swift 3 and iOS 10 push notifications, using your own custom Node.js server. Please note that there are plenty of alternatives to the custom server solution I will present here, like Firebase and similar services, these will start charging you a monthly fee after you reach a certain number of users. Using your own server is advantageous if you want complete control over what software you run on it and how you store and use your data.
If you want to follow this tutorial you will need to be a paying member of the Apple Developer Program and have an iOS device. It is also recommended, but not required, that you have a working web server with root access. Personally, I tend to use DigitalOcean, but you can use any VPS provider. For the purpose of this article, I will show you how to use a local web server.
Start by creating a new iOS, Single View Application, make sure that you’ve filled all required fields for the project options:
Once the project is created, open the Capabilities panel and toggle the Push Notifications button:
If, after you’ve enabled the push notifications capabilities, you see something red, close and reopen Xcode.
Next, log in to your Apple Developer account and, from the left panel, select Certificates, IDs & Profiles. Under Certificates select APNs Auth Key:
Use the + button to create a new certificate. On the What type of certificate do you need? page, scroll down and select Apple Push Notifications Authentication Key (Sandbox & Production:
Press Continue at the bottom of the page.
On the next page make a note of the Key ID and download the certificate:
Be sure to store a copy of the certificate in a safe place.
Before leaving the Apple Developer page, go to your account, select Membership and make a note of your Team ID:
Time to write some actual code!
Open AppDelegate.swift and import the UserNotifications module:
Next, in the application(_:didFinishLaunchingWithOptions:) prepare to ask the user to authorize the use of notifications for this application:
Now, we can add three callback functions to manage the remote notifications:
If the application was correctly configured and the user accepts to receive remote notifications the first function from above will be called with a device token that uniquely identifies the application and the user device. This device token is used to push, or send, notifications to a particular user and device. In a real world application you will need to save the token for each user in a database. For the purpose of this article we will simply copy the device token and use it directly in the server code. Please note that the device token can be changed by iOS, for example if the user reinstalls the application, in this case you will need to resend it to the notification server.
We can print the device token in the debug console:
If the registration failed we’ll print the error:
Next, we can print the actual notification:
When you will first run the application on your device you will be asked if you want to accept notifications from the application:
Make a note of your particular device token, for example in my case the token looks like this:
Next, install Node.js if it is not already installed on your machine. Obviously, you can install Node.js on a dedicated server if possible.
In order to send notifications to Apple’s servers we will use node-apn. Open a Terminal and install the prerequisites:
Copy the .p8 certificate file previously saved in the notification_server folder, for simplicity I’ve renamed this cert_notifications.p8. Create a file named server.js:
Pay attention that you need to change keyID, teamID, deviceToken and notification.topic for your particular settings.
You can run the code with:
This is what I see on my phone if I run the above code:
If you want to learn more about Swift and iOS programming I would recommend reading Swift Programming by Matthew Mathias and John Gallagher:
or iOS Programming by Christian Keur and Aaron Hillegass: