Logo for tanaschita.com

How to add custom actions for iOS push and local notifications

Learn about actionable notifications that allow users to respond without launching the app.

21 Mar 2022 · 4 min read

iOS local and push notifications allow us to keep users up to date or get reminded of time or location sensitive events, even if the app is running in the background or is inactive.

When using actionable notifications, the iOS system displays one or more buttons in addition to the notification content. They allow the user to respond to a delivered notification without launching the app.

Notification with two actions.
Notification with two actions

Let's see how to create an actionable notification and handle the user's response.

Creating notification actions

To add actions to a notification, two steps are required.

  1. Creating a category and its actions and registering it with UNUserNotificationCenter at launch time.

  2. Adding the category id to the notification payload.

Sponsorship logo
Preparing for a technical iOS job interview
Check out my new book on preparing for a technical iOS job interview with over 200 questions & answers. Test your knowledge on iOS topics such as Swift & Objective-C, SwiftUI & UIKit, Combine, HTTP Networking, Authentication, Core Data, Concurrency with async/await, Security, Automated Testing and more.
LEARN MORE

Step 1: Creating and registering a category and its actions

A notification action is represented by the UNNotificationAction and a category by the UNNotificationCategory type.

let doneAction = UNNotificationAction(identifier: "drinkingReminder.doneAction", title: "Done", options: [])
let notThirstyAction = UNNotificationAction(identifier: "drinkingReminder.notThirstyAction", title: "Not thirsty", options: [])
let drinkingReminderCategory = UNNotificationCategory(
identifier: "drinkingReminderCategory",
actions: [doneAction, notThirstyAction],
intentIdentifiers: [],
options: .customDismissAction)
UNUserNotificationCenter.current().setNotificationCategories([drinkingReminderCategory])

In the code above, we create a category with two actions. Then we use the setNotificationCategories method of UNUserNotificationCenter to register the category.

Step 2: Adding the category id to the notification payload

To use the category on a local notification, we set the categoryIdentifier on UNMutableNotificationContent when creating it.

let content = UNMutableNotificationContent()
content.title = "Stay hydrated"
content.body = "It's time for a glass of water"
content.sound = .default
content.categoryIdentifier = "drinkingReminderCategory"

To use the category on a remote notification, the server can include the identifier in the payload.

{
"aps" : {
"alert" : {
"title" : "Stay hydrated",
"body" : "It's time for a glass of water"
},
"sound": "default",
"category" : "drinkingReminderCategory"
}
}

Handling notification actions

When the user taps one of the notification actions, the iOS app is launched in the background and the delegate method userNotificationCenter(_:didReceive:withCompletionHandler:) is called. Here, we can use response.actionIdentifier to switch through the actions and handle them.

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
switch response.actionIdentifier {
case "drinkingReminder.doneAction":
// Handle action
case "drinkingReminder.notThirstyAction":
// Handle action
default:
break
}
completionHandler()
}

Beware that there is no possibility to switch between categories, so every action need a unique identifier.

To add more safety to our code, we may extract the ids into enums to avoid dealing with strings in different places.

enum NotificationAction {
case drinkingReminderDone
case drinkingReminderNotThirsty
var id: String {
switch self {
case .drinkingReminderDone:
return "tanaschita.notificationAction.drinkingReminder.done"
case .drinkingReminderNotThirsty:
return "tanaschita.notificationAction.drinkingReminder.notThirsty"
}
}
}

Conclusion

Notification actions provide a great way to allow users to respond to a notification without having to open the app.

One additional thing to consider is that we may not be able to access files on disk while the app is in the background for example when the device is locked. In this case, an additional solution is needed like saving the response temporarily until we get the file access.

Sponsorship logo
Preparing for a technical iOS job interview
Check out my new book on preparing for a technical iOS job interview with over 200 questions & answers. Test your knowledge on iOS topics such as Swift & Objective-C, SwiftUI & UIKit, Combine, HTTP Networking, Authentication, Core Data, Concurrency with async/await, Security, Automated Testing and more.
LEARN MORE

Newsletter

Image of a reading marmot
Subscribe

Like to support my work?

Say hi

Related tags

Articles with related topics

notifications

swift

ios

Developer guide on push notifications for iOS

Learn how to setup and handle remote push notifications.

21 May 2023 · 5 min read

Latest articles and tips

© 2023 tanaschita.com

Privacy policy

Impressum