< Previous: Scheduling notifications: UNUserNotificationCenter and UNNotificationRequest | Next: Wrap up > |
There’s a lot more you can do with notifications, but chances are the thing you most want to do is act on the user’s response – to show one or more options alongside your alert, then respond to the user’s choice.
We already set the categoryIdentifier
property for our notification, which is a text string that identifies a type of alert. We can now use that same text string to create buttons for the user to choose from, and iOS will show them when any notifications of that type are shown.
This is done using two new classes: UNNotificationAction
creates an individual button for the user to tap, and UNNotificationCategory
groups multiple buttons together under a single identifier.
For this technique project we’re going to create one button, “Show me more…”, that will cause the app to launch when tapped. We’re also going to set the delegate
property of the user notification center to be self
, meaning that any alert-based messages that get sent will be routed to our view controller to be handled.
Creating a UNNotificationAction
requires three parameters:
.authenticationRequired
, .destructive
, and .foreground
.Once you have as many actions as you want, you group them together into a single UNNotificationCategory
and give it the same identifier you used with a notification.
That’s it! Add this method to ViewController
now:
func registerCategories() {
let center = UNUserNotificationCenter.current()
center.delegate = self
let show = UNNotificationAction(identifier: "show", title: "Tell me more…", options: .foreground)
let category = UNNotificationCategory(identifier: "alarm", actions: [show], intentIdentifiers: [])
center.setNotificationCategories([category])
}
You might have noticed the empty intentIdentifiers
parameter in the category initializer - this is used to connect your notifications to intents, if you have created any.
You’ll get an error because you assigned self
to be the delegate of the user notification center. To fix it, make the ViewController
class conform to UNUserNotificationCenterDelegate
like this:
class ViewController: UIViewController, UNUserNotificationCenterDelegate {
You can call registerCategories()
wherever you want, but in this project the safest place is probably right at the beginning of the scheduleLocal()
method.
Now that we have registered the “alarm” category with a single button, the last thing to do is implement the didReceive
method for the notification center. This is triggered on our view controller because we’re the center’s delegate, so it’s down to us to decide how to handle the notification.
We attached some customer data to the userInfo
property of the notification content, and this is where it gets handed back – it’s your chance to link the notification to whatever app content it relates to.
When the user acts on a notification you can read its actionIdentifier
property to see what they did. We have a single button with the “show” identifier, but there’s also UNNotificationDefaultActionIdentifier
that gets sent when the user swiped on the notification to unlock their device and launch the app.
So: we can pull out our user info then decide what to do based on what the user chose. The method also accepts a completion handler closure that you should call once you’ve finished doing whatever you need to do. This might be much later on, so it’s marked with the @escaping
keyword.
Here’s the code – add this method to ViewController
now:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
// pull out the buried userInfo dictionary
let userInfo = response.notification.request.content.userInfo
if let customData = userInfo["customData"] as? String {
print("Custom data received: \(customData)")
switch response.actionIdentifier {
case UNNotificationDefaultActionIdentifier:
// the user swiped to unlock
print("Default identifier")
case "show":
// the user tapped our "show more info…" button
print("Show more information…")
default:
break
}
}
// you must call the completion handler when you're done
completionHandler()
}
Our project now creates notifications, attaches them to categories so you can create action buttons, then responds to whichever button was tapped by the user – we’re done!
SAVE 50% All our books and bundles are half price for Black Friday, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.
Link copied to your pasteboard.