Local Notifications: Getting Started
Learn how to create notifications by time intervals, time of day and location, as well as how to support category grouping and prompting for action. By Vidhur Voora.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Local Notifications: Getting Started
25 mins
- Getting Started
- Introducing Notifications
- Requesting Notification Permission
- Prompting Notification Authorization
- Understanding Critical Notifications
- Creating Notifications
- Triggering TimeInterval Notifications
- Scheduling the Notification
- Viewing Notification When the App Is in the Foreground
- Removing Scheduled Notifications
- Triggering Calendar Notifications
- Triggering Location Notifications
- Creating a Location Trigger
- Grouping Notifications
- Handling Notification Actions
- Declaring Category and Creating Actions
- Assigning Identifiers to Notification Payload
- Handling Actions
- Where to Go From Here?
Scheduling the Notification
Open TaskManager.swift. Add the following to save(task:)
after the DispatchQueue.global().async
block and before the method ends:
if task.reminderEnabled {
NotificationManager.shared.scheduleNotification(task: task)
}
Here, you schedule a notification if the task has reminderEnabled
set to true
.
Build and run.
Follow these steps to add a task and test your notification:
- Tap the + button to start adding a task.
- Give the task a name.
- Toggle the Add Reminder switch.
- Use the default selection Time with the Time Interval set to one minute.
- Leave Repeat Notification off.
- Tap Save at the top right to create the task.
Finally, background the app and wait for one minute. You’ll see the notification appear.
Congratulations on your first notification! :]
To view this notification, you had to background the app and wait. Wouldn’t it be cool to view the notification while the app is still in the foreground? You’ll do that next.
Viewing Notification When the App Is in the Foreground
Open AppDelegate.swift and add the following to the end of the file:
// MARK: - UNUserNotificationCenterDelegate
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void
) {
completionHandler(.banner)
}
}
userNotificationCenter(_:willPresent:withCompletionHandler:)
asks the delegate how to handle a notification when the app is in the foreground. Here, you call the completion handler with the presentation option set to a banner
. You can also add other options, such as sound
and badge
.
Next, add the following to AppDelegate
:
private func configureUserNotifications() {
UNUserNotificationCenter.current().delegate = self
}
Here, you declare configureUserNotifications()
, which makes AppDelegate
the delegate for UNUserNotificationCenter
.
Now, add the following to application(_:didFinishLaunchingWithOptions:)
before returning true
:
configureUserNotifications()
Here, you call configureUserNotifications()
to set the notification delegate as soon as the app launches.
Build and run.
To try it out, add a task with a time interval set to one minute and leave the app in the foreground. You’ll see a notification appear while the app is in the foreground. Great job!
Marking a task done deletes it, but what about the notification? You don’t want to see a reminder for a task that isn’t present. You’ll work on that next.
Removing Scheduled Notifications
Open NotificationManager.swift and add the following to NotificationManager
:
func removeScheduledNotification(task: Task) {
UNUserNotificationCenter.current()
.removePendingNotificationRequests(withIdentifiers: [task.id])
}
You need to ensure the removal of any pending notification upon task completion. Do this by using removePendingNotificationRequests(withIdentifers:)
. Here, you pass the identifier of the task in an array. This is especially useful for tasks that have repeats
set to true
.
Next, open TaskManager.swift and add the following to remove(task:)
before returning:
if task.reminderEnabled {
NotificationManager.shared.removeScheduledNotification(task: task)
}
This removes any scheduled notification once the task finishes.
Build and run.
Give this a try by creating a task with a time interval of one minute. This time, toggle the Repeat Notification switch to enable it. You’ll notice the notification appears every minute. Next, mark the created task complete by tapping the circle button next to the task. This will delete the task and you’ll no longer see the scheduled notifications for this task.
You can use removeAllPendingNotificationRequests()
on UNUserNotificationCenter
to unschedule all the pending notifications. removeAllDeliveredNotifications()
will remove all the delivered notifications.
The time interval is just one way to trigger a notification. There are other ways to trigger notifications locally: calendar and location. You’ll implement these next.
Triggering Calendar Notifications
Open NotificationManager.swift. Then, add the following to scheduleNotification(task:)
as an additional case in switch task.reminder.reminderType
:
case .calendar:
if let date = task.reminder.date {
trigger = UNCalendarNotificationTrigger(
dateMatching: Calendar.current.dateComponents(
[.day, .month, .year, .hour, .minute],
from: date),
repeats: task.reminder.repeats)
}
With the code you added, you:
- Check if the
reminder
of thetask
has adate
set. - Create a notification trigger of type
UNCalendarNotificationTrigger
. The calendar trigger delivers a notification based on a particular date and time. It extractsdateComponents
from the date the user selected. Specifying only the time components will trigger a notification at that specified time.
Build and run.
Follow these steps to create a task:
- Tap the + button.
- Give the task a name.
- Toggle the Add Reminder switch.
- Tap the Date trigger in the segment bar.
- Select a particular date and time — maybe one minute from now.
- Leave Repeat Notification off.
- Tap the Save button to create the task.
You’ll see the notification appear. Congratulations on your first calendar notification!
Calendar notifications let you schedule a recurring reminder of a daily routine, such as drinking water every morning.
Now, it’s time to add a reminder to buy GME stock when you pass a GameStop store. :] Enter location-based reminders!
Triggering Location Notifications
The location-based trigger causes the app to deliver a notification when the user enters or exits a region. Behind the scenes, iOS uses geofences for region monitoring. As such, the system limits the number of location-based triggers that the user can schedule at the same time.
The first step to adding a location-based notification is to request location permission. Because the system monitors the regions, the app needs the When-In-Use authorization. The location authorization and delegate code already exist for you in LocationManager.swift.
Open CreateTaskView.swift. Then, find and replace // TODO: Request location authorization
with the following:
locationManager.requestAuthorization()
Here, you request location authorization when the user taps the Request Location Authorization button — the user hasn’t already granted authorization.
Creating a Location Trigger
Open NotificationManager.swift. Next, add the following to scheduleNotification(task:)
by replacing the default
case in switch task.reminder.reminderType
:
case .location:
// 1
guard CLLocationManager().authorizationStatus == .authorizedWhenInUse else {
return
}
// 2
if let location = task.reminder.location {
// 3
let center = CLLocationCoordinate2D(
latitude: location.latitude,
longitude: location.longitude)
let region = CLCircularRegion(
center: center,
radius: location.radius,
identifier: task.id)
trigger = UNLocationNotificationTrigger(
region: region,
repeats: task.reminder.repeats)
}
Here’s a step-by-step breakdown:
- You check if the user has granted at least When In Use location authorization.
- Then, you check to make sure the location data exists for the task reminder.
- You create location-based triggers using
UNLocationNotificationTrigger
. First, you define a center denoted byCLLocationCoordiante2D
. Using this, you create an instance ofCLCircularRegion
by specifying the radius and a unique identifier. Finally, you create the trigger using this circular region. You can specify whether to trigger the notification only when entering the region or when exiting the region by usingnotifyOnEntry
andnotifyOnExit
onCLCircularRegion
.
Build and run.
Tap the + button to start adding a task. Next, tap Location in the segment bar. Then, tap Request Location Authorization if you haven’t granted location authorization already. Now, select Allow While Using App in the location permission prompt. You’ll see Latitude, Longitude and Radius text fields appear.
Enter the latitude and longitude of a place you plan to visit soon or the coordinates of your home. Enter 500 for the radius. This value is in meters. Then, tap Save to create the task.
You’ll now receive a notification when you enter or exit the location you specified. To simulate this, go to the simulator Features menu, select Location ▸ Custom Location… and enter the same latitude and longitude values at the prompt. You’ll see the notification appear from your app in the background. Way to go!
So far, you’ve created notifications based on different triggers. But it would be cool to group these notifications based on the trigger, right? You’ll do that next.