Send Push Notifications to iOS Devices Via .p8 file (Xcode 8 and Swift 3)

Published Jun 10, 2017
Send Push Notifications to iOS Devices Via .p8 file (Xcode 8 and Swift 3)

An engaging app is the one that that keeps their customers and users on their toe for an update of their products or services. But doing so in the iOS is a bit challenging, particularly with all of the changes in Xcode and Swift. Above all, the challenging segment is the enabling of Push Notifications in the various iOS versions that restrict notification classes.

Despite the entire internet filled with guides describing the implementation of iOS push notifications, most are widely vague and complicated, or aren’t up to date with the latest Swift 3 and XCode  8. In addition to these the guides do not provide the provide backward-compatibility with all iOS versions that support Swift (iOS 7 – iOS 10) and also the usage of new APNs Auth Keys is neglected which makes things easier in sending Push Notifications.

This guide walks you through the implementation of push notifications in your iOS app, using the latest in this segment without much annoyance.

Preparations

First off, open your iOS project in Xcode 8 Update your XCode8 from the Appstore if you don’t have it; and also create an iOS project, if you haven’t created one before. Make sure that your codebase has been updated to use Swift 3.

image003.png

Secondly, having an active Apple Developer Program Membership is a necessity. It costs $100/year and is a requirement in order to send Push Notifications to your iOS App. In addition also make sure that the Xcode and iCloud accounts are configured which contains the active Developer Program Membership.

Third, make sure that Bundle Identifier has been configured in the project editor of your app:

Enabling Push Notifications

The initial step in setting up push notifications is facilitating the feature within Xcode 8 for your app.

Go on to the project editor for your target and then click on the Capabilities tab. Locate Push Notifications and change its value to ON :

Xcode should display two checkmarks indicating that the capability was successfully enabled. Behind the scenes, Xcode creates an App ID in the Developer Center and enables the Push Notifications service for your app.

image005.png

Registering Devices

Devices need to be uniquely identified to receive push notifications.

Each and Every device on which your app has been installed is assigned a unique device token by APNs that can be used to push at any given time. Once those devices have been assigned a unique token, it should be carried on in your backend database.

A sample device token looks like this:

8F93MDUI4O3MO9FM3859FMDLWN3P5MFMEU3094N5ND8D03MNFUVOD093Y

To request a device token for the current device, open AppDelegate.swift and add the following to the didFinishLaunchingWithOptions callback function, before the return statement:

// iOS 10 support

if #available(iOS 10, *) {

UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]){ (granted, error) in }

application.registerForRemoteNotifications()

}

// iOS 9 support

else if #available(iOS 9, *) {

UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))

UIApplication.shared.registerForRemoteNotifications()

}

// iOS 8 support

else if #available(iOS 8, *) {

UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))

UIApplication.shared.registerForRemoteNotifications()

}

// iOS 7 support

else {

application.registerForRemoteNotifications(matching: [.badge, .sound, .alert])

}

In iOS 10, a new framework called UserNotifications was previously introduced which must be imported in order to access the UNUserNotificationCenter class.

Add the following import statement to the top of AppDelegate.swift:

import UserNotifications

After which, visit the project editor for your target, and in the General tab, look for the Linked Frameworks and Libraries section.

Click + and select UserNotifications.framework:

image007.png

Next, add the subsequent callbacks in AppDelegate.swift;this will be invoked when APNs has either successfully registered or failed registering the device to receive notifications:

// Called when APNs has assigned the device a unique token

funcapplication(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceTokendeviceToken: Data) {

// Convert token to string

let token = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})

 

// Print it to console

print("APNs device token: \(token)")

 

// Persist it in your backend in case it's new

}

 

// Called when APNs failed to register the device for push notifications

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {

// Print the error to console (you should alert the user that registration failed)

print("APNs registration failed: \(error)")

}

Implementation of logic that will persist the token in your application backend is all up to you. This guide at a later stage, backend server will connect to APNs and send push notifications by providing this very same device token to indicate which device(s) should receive the notification.

Note: The device token used may change at later stages due to various reasons, so use NSUserDefaults, a local key-value store, to carry on the token locally and update your backend only when the token has changed in order to avoid unnecessary requests.

After making the necessary modifications to AppDelegate.swift, run your app on a physical iOS device (the iOS simulator cannot receive notifications)

Look for the following dialog, and press OK to permit your app to receive push notifications:

image009.png

Within seconds, your device’s unique token should be displayed on the Xcode console. Copy it and save it for later.

Prepare to Receive Notifications

Add the following callback in AppDelegate.swift which will be invoked when your app receives a push notification sent by your backend server:

// Push notification received

func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {

// Print notification payload data

print("Push notification received: \(data)")

}

Note : This callback will only be invoked when the user has either clicked or swiped to interact with your push notification from the lock screen / Notification Center, or if your app was open when the push notification was received by the device.

Development of the actual logic that gets carried out when a notification is interacted with is up to you.

Example: if you have a messenger app, a “new message” push notification would unlock the related chat page and cause the list of messages to be updated from the server.

Data object could be made use of, which contains any data that you send from your application backend, such as the chat ID, used in the messenger app example.

Another important note is that, if your app is open when a push notification is received, the user will not see the notification at all. This StackOverflow question lists some possible workarounds for such instances, ex: displaying an in-app banner similar to the stock iOS notification banner.

How to Generate an APNs Auth Key?

Generating an authentication key is the next crucial step that will allow your backend server to authenticate with APNs when it wants to send one or more of your devices a push notification.

The process to achieve this was a painful task a few months ago. Thankfully, Apple has greatly simplified the process of authenticating with APNs with the introduction of APNs Auth Keys, which never expire (unless revoked by you) and work for all deployment schemes.

Open the APNs Auth Key page in your Developer Center and click the + button to create a new APNs Auth Key.

In the next page, select Apple Push Notification Authentication Key (Sandbox & Production) and click Continue at the bottom of the page.

image011.png

Apple will then generate a .p8 key file containing your APNs Auth Key.

image013.png

Download the .p8 key file to your computer and save it for later. Also, be sure to write down the Key ID somewhere, as you’ll need it to send the push notification form server side.

Things needed to be provided for the Backend developers to send push notifications are:

1)       .p8 file downloaded from Apple developer console.

2)       Package Bundle Identifier for your app(‘com.quadkast.pushnotification’ in my case ).

3)       Key ID 😕/ The Key ID of the p8 file

4)       Team ID: // The Team ID of your Apple Developer Account (available at https://developer.apple.com/account/#/membership/))

Discover and read more posts from Ramachandran Gunasekeran
get started