Push Notifications Tutorial: Getting Started

Push notifications allow developers to reach users, even when users aren’t actively using an app! In this tutorial, you’ll learn how to configure your app to receive push notifications and to display them to your users or perform other tasks. By Chuck Krutsinger .

4.9 (27) · 2 Reviews

Download materials
Save for later
Share
You are currently viewing page 2 of 4 of this article. Click here to view the first page.

Registering With APNs

Now that you have permissions, you’ll register for remote notifications!

In getNotificationSettings(), add the following beneath the print inside the closure:

guard settings.authorizationStatus == .authorized else { return }
DispatchQueue.main.async {
  UIApplication.shared.registerForRemoteNotifications()
}

Here, you verify the authorizationStatus is .authorized: The user has granted notification permissions. If so, you call UIApplication.shared.registerForRemoteNotifications() to kick off registration with the Apple Push Notification service. You need to call this on the main thread, or you’ll receive a runtime warning.

Add the following to the end of AppDelegate:

func application(
  _ application: UIApplication,
  didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
  let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
  let token = tokenParts.joined()
  print("Device Token: \(token)")
}

This method is called by iOS whenever a call to registerForRemoteNotifications() succeeds. The code may look cryptic, but it’s simply taking a received deviceToken and converting it to a string. The device token is the fruit of this process. It’s provided by APNs and uniquely identifies this app on this particular device.

When sending a push notification, the server uses tokens as “addresses” to deliver to the correct devices. In your app, you would now send this token to your server to save and use later on for sending notifications.

Now add the following:

func application(
  _ application: UIApplication,
  didFailToRegisterForRemoteNotificationsWithError error: Error
) {
  print("Failed to register: \(error)")
}

This method is called by iOS if registerForRemoteNotifications() fails. You’re just printing the error for now.

That’s it! Build and run. Because you are on a simulator, you’ll see a Failed to register error. You can ignore that for now. Later, when you run on a real device, you should receive a token in the console output. Here’s an example:

Example of a device token

Note: There are several reasons why registration might fail. Most often, it’s because the App ID was not properly configured. The error message generally provides a good hint for what’s wrong.

Sending a Simulated Push Notification

Use a text editor to create a file called first.apn, which you’ll pass to Xcode’s simctl utility. Paste in the following JSON text and save the file.

{
  "aps": {
    "alert": "Breaking News!",
    "sound": "default",
    "link_url": "https://raywenderlich.com"
  }
}

The structure of this JSON will be explained in the next section. Patience, grasshopper.

Build and run the app again on the simulator, then background the app or lock the device. The app is not yet able to process push notifications while in the foreground.

To use simctl, you’ll need to know the device identifier for the simulator that you are running the app in. If there is only one device running in the simulator, you can use booted instead of an identifier. To get the identifier, in Xcode, select Windows ▸ Devices and Simulators, then select the Simulators tab at the top and select the simulator you’re using from the list on the left. Use your mouse to copy the identifier. You might need to widen the dialog box to see it fully.

Finding the device identifier in Xcode

Open the Terminal app and change to the directory where you saved first.apn. Then type in the following command using either booted or the device identifier from Xcode in place of device_identifier: xcrun simctl push device_identifier bundle_identifier first.apn. Replace device_identifier with the device identifier you copied from Xcode and replace bundle_identifier with the app’s bundle identifier — the one you used when you first set up the project. Here’s an example:

Using xcrun simctl to send a push notification from the terminal

Run the command and you’ll see the push notification appear on the simulator!

Push notification appears on simulator

Tap on the notification to launch the app.

App launched from the push notification

Isn’t that cool? :]

Looking at a Basic Push Notification

Before you move on to handling push notifications, take a look at the body of the notification you’ve sent:

{
  "aps": {
    "alert": "Breaking News!",
    "sound": "default",
    "link_url": "https://raywenderlich.com"
  }
}

The payload is a JSON dictionary that contains at least one item, aps, which is also a dictionary. In this example, aps contains the fields alert, sound, and link_url. When the device receives this push notification, it shows an alert view with the text “Breaking News!” and plays the standard sound effect.

link_url is actually a custom field. You can add custom fields to the payload like this, and they will get delivered to your application. Because you aren’t handling it inside the app yet, this key/value pair currently does nothing.

Correction: An astute reader pointed out that Apple’s documentation states that custom content such as link_url should be at a peer level to the aps dictionary entry rather than inside of it. It still works if you place it inside, but we always suggest adhering to Apple’s documentation and will correct this in our next update to this tutorial.

There are eight built-in keys you can add to the aps dictionary (see the official Payload Key Reference for more information):

  • alert: This can be a string, as in the previous example, or a dictionary. As a dictionary, it can localize the text or change other aspects of the notification.
  • badge: This is a number that will display in the corner of the app icon. You can remove the badge by setting this to 0.
  • sound: Name of a custom notification sound’s file located in the app. These must be shorter than 30 seconds.
  • thread-id: Use this key to group notifications.
  • category: This defines the category of the notification, which is used to show custom actions on the notification. You’ll explore this shortly.
  • content-available: By setting this key to 1, the push notification becomes silent. You’ll learn about this in the Silent Push Notifications section below.
  • mutable-content: By setting this key to 1, your app can modify the notification before displaying it.
  • target-content-id: This is the identifier of the window brought forward.

Outside of these, you can add as much custom data as you want, as long as the payload does not exceed 4,096 bytes.

Once you’ve had enough fun trying out these options and sending push notifications to your simulator, move on to the next section!

Chuck Krutsinger

Contributors

Chuck Krutsinger

Author

Keegan Rush

Author

Mark Powell

Tech Editor

Luke Freeman

Illustrator

Adrian Strahan

Final Pass Editor

Richard Critz

Team Lead

Over 300 content creators. Join our team.