Adding actions to notifications

When we covered the different ways for you to handle notifications in your app, you briefly saw that the notification response that is passed to userNotificationCenter(_:didReceive:withCompletionHandler:) contains information about the action the user chose for the notification. By default, every notification has a single action, which is triggered when the user taps or swipes your notification, depending on where it appeared, to open your app.

This default action isn't the only type of action that can be associated with a notification. There are three main kinds of actions that notification support. The first is a background action. Background actions dismiss the notification and wake the app in the background so it can take appropriate measures for the selected action. An example of this is accepting a calendar invite through an action. If a user accepts or declines an invite inside the notification, we don't really need to take them to the app. We can handle their response in the background.

The second type of action is a foreground action. A foreground action will take the user right into your app. It's up to your app to handle the selected action in a way that makes sense. Finally, you can add test input actions to your notifications. These types of action are basically background actions, except they take user input. A text input action is great if you're building a messaging app, for example. In addition to these standard actions, the user can 3D-touch a notification to make custom actions appear. Let's see how you can add these custom actions to our notifications.

All notification actions are associated with a notification category. These categories must be registered with the Notification Center at app launch. Again, the perfect place to set this up is application(_:didFinishLaunchingWithOptions:). Add the following implementation to this method:

let favoriteAction = UNNotificationAction(identifier: "addfavorite", title: "Favorite", options: [])
let viewAction = UNNotificationAction(identifier: "view", title: "View in app", options: [.foreground])

let quoteCategory = UNNotificationCategory(identifier: "quote", actions: [favoriteAction, viewAction], intentIdentifiers: [], options: [])
UNUserNotificationCenter.current().setNotificationCategories([quoteCategory])

The preceding snippet adds two custom actions to a category we've named quote. One action is used to mark a quote as favorite and is handled in the background. The other allows the user to view the quote in the app and is marked explicitly to run in the foreground. If we hadn't done this, the action would have been handled in the background. Finally, the category is added to the notification center, allowing us to associate this category with new notifications.

Associating a category with a notification is done through the categoryIdentifier property of UNNotificationContent. Add the following line of code to the createNotification method in ViewController to add the quote category to the notifications we're scheduling:

content.categoryIdentifier = "quote"

If you 3D-touch the received notification now, you're presented with two custom actions:

Notification actions are a great way to add quick interactions to your notifications, and they are already a huge improvement over simply sending a plain notification. There is one more feature that greatly improves notifications and their usefulness: Notification Extensions.