Home iOS & Swift Books Push Notifications by Tutorials

4
Xcode Project Setup Written by Scott Grosch

Before you start sending and receiving push notifications, you first need to make sure your project is set up to do so!

Open Xcode and create a new “Single View App” project. You may leave the checkmarks at the bottom of the project creation screen unchecked, as you won’t need Core Data or any tests in your project. In the Bad Ol’ Days, this is the point in which you’d have to set up a custom profile with Apple to enable push notifications. Fortunately, with the current toolchains, this is all automated now.

Adding capabilities

To tell Xcode that you’ll be using push notifications in this project, just follow these four simple steps so that it can handle the registration for you:

  1. Press + 1 (or View ▸ Navigators ▸ Show Project Navigator) to open the Project Navigator and click on the top-most item (e.g. your project).
  2. Select the target, not the project.
  3. Select the Signing & Capabilities tab.
  4. Click the + Capability button in the top right corner.
  5. Search for and select Push Notifications from the menu that pops up.
  6. Notice the Push Notifications capability added below your signing information.

If you were to go back to the Member Center now and look at your provisioning profiles, you’d see that one has been generated specifically for this project with push notifications enabled. Well, that was so easy that it makes you wonder why Apple didn’t make it this easy from day one!

Registering for notifications

You’ve told Apple that you’re going to send push notifications. Next, you’ll have to add the required code to prepare your app for receiving push notifications. As push notifications are an opt-in feature, you’ll have to request permissions from the user to enable them.

Because users can turn off notifications at any point, you need to check for whether or not they are enabled every time the app starts. The very first time, and only the very first time that your app requests access to push notifications, iOS will display an alert asking the user to accept or reject notifications. If the user accepts, or has previously accepted, you can tell your app to register for notifications.

Open up AppDelegate.swift and replace its contents with the following code:

import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder {
  var window: UIWindow?
}

extension AppDelegate: UIApplicationDelegate {
  func application(_ application: UIApplication,
                   didFinishLaunchingWithOptions launchOptions:
                        [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    UNUserNotificationCenter.current().requestAuthorization(options: [
      .badge, .sound, .alert
    ]) { granted, _ in
      guard granted else { return }

      DispatchQueue.main.async {
        application.registerForRemoteNotifications()
      }
    }

    return true
  }
}

Notice the addition of a new import statement to pull in the UserNotifications system framework. It’s a bit hard to read due to the long length of the function name but, essentially, whenever the app starts, you request authorization from the user to send badges, sounds and alerts to the user. If any of those items are granted by the user, you register the app for notifications.

Note: The notification closure is not run on the main thread, so you must dispatch the actual registration method to the main thread of your app using the main DispatchQueue.

In order to test push notifications, you’ll have to run the app on an actual device, and not in the simulator. If you build and run your app now, you’ll see the request to allow notifications.

Since you’re reading this book, you must want to see the notifications, so click on Allow in the alert.

Provisional authorization

An alert like the one above can be somewhat jarring to a user when the app starts up the first time. Why are they being asked for this? What type of data are you going to send? If you talk to your friends and colleagues, you’ll likely find that a surprising number of people, especially older people, simply reject all notifications.

To work around this issue, Apple provides another useful case for the UNAuthorizationOptions enum that you can pass to requestAuthorization during setup. If you include .provisional in the options argument, notifications will automatically be delivered silently to the user’s Notification Center, without asking for permission – there will be no sound or alerts for these provisional notifications.

The benefit of this option is that users who look in Notification Center can see your notifications and decide if they’re interested in them or not. If they are, they simply authorize them from there, resulting in future notifications appearing as regular push notifications.

That’s quite a nice feature to include via a simple flag!

Critical alerts

There’s another type of authorization that you might need to request, depending on the type of app you’re building. If your app has something to do with health and medical, home and security, public safety or anything else that may have the need to present a notification even if the user declined alerts, you can ask Apple to configure critical alerts via the .criticalAlert enum case. Critical alerts will bypass the Do Not Disturb and ringer switch settings as well as always play a sound… even a custom sound.

Due to the disruptive nature of critical alerts, you must apply for a special entitlement from Apple to enable them. You can do that through the Apple Developer Portal (https://apple.co/2JwRvbv)

Getting the device token

If your app successfully registered for notifications, iOS will call another delegate method providing a device token to your app. The token is an opaque data type which is globally unique and identifies one app-device combination with the APNs.

Unfortunately, iOS provides this to you as a Data type instead of a String, so you’ll have to convert it since most push service providers expect a string.

Paste the following code into your AppDelegate extension:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
  let token = deviceToken.reduce("") { $0 + String(format: "%02x", $1) }
  print(token)
}

The token is basically a set of hex characters; the above code simply turns the token into a hex string. There are multiple methods that you’ll see on the internet for how to convert the Data type to a String. Use whatever method seems most natural to you. reduce is a method that combines the elements of a sequence into a single value using the given closure. So, in this case, you’re simply taking each byte and converting it to hex, then appending it to the accumulated value.

Note: Never make an assumption about the length of the token. Many tutorials you find will hardcode the length of a token for efficiency. Apple has already increased the token length once before from 32 to 64 characters. When you store your device tokens in something like a SQL database, be sure to not hardcode a length or you may have issues in the future.

Also, keep in mind that the device token itself can change. Apple will issue a new device token when the user installs the app on another device, restores from an old backup, reinstalls iOS and in some other cases. You should never try and link a token to a specific user.

Build and run the app. You should see a device token (a string of random characters) in the Xcode console window:

Key points

  • You must tell Xcode that push notifications will be part of your project; follow the steps in this chapter so that Xcode can handle the registration for you.
  • You must add the required code to prepare your app for receiving push notifications.
  • Push notifications are an opt-in feature, so you must request permissions from the user to enable them.
  • To avoid jarring notifications the first time a user opens an app, use provisional authorization so that notifications are delivered silently to the user’s Notification Center, without asking for permission.
  • For critical alerts that override a user’s declined alerts, you must apply for a special entitlement from Apple to enable them, due to their disruptive nature.
  • Once you have successfully registered your app for notifications, iOS will call a delegate method, providing a device token to your app. Never make assumptions about the length of your token or try to link the token to a specific user.

Where to go from here?

At this point, you’ve technically done everything necessary to make your app capable of receiving and displaying a push notification. In the next chapter, you’ll get your Authentication Token from Apple so that Apple’s servers will allow you to send notifications and you’ll finally send your first push notification!

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.

Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:

© 2021 Razeware LLC