Local Notifications with Swift
Here you’ll learn how to schedule and handle local notifications into your iOS app with Swift.
We will go through the below mentioned sequence to understand Local Notifications:
- Understanding of Types of Notifications
- Create a NotificationManagerClass to handle and schedule Local Notifications
- User’s Permission to Send Local Notifications
- Local Notification Permission Status
- Schedule Local Notifications
- Handle Incoming Local Notifications
Understanding of Types of Notifications
On iOS, we can send and receive two types of notifications:
- Push Notifications: Push notifications are sent via the internet, such as chat messages. It gets delivered to user’s iPhone Device via Apple Push Notification Service (APNS).
- Local Notifications: Local notifications are scheduled and sent locally on our iPhone, so we don’t require internet on our phone to receive it. For example, calendar reminders or iPhone alarm clock reminders.
In this post, we’ll focus on local notifications. Local notifications are short, text-based messages that you can schedule from within the iOS app, to be delivered at a future point in time. It can be in a recurring form as well.
Local notifications are ideal for use cases like, reminding a user about an upcoming calendar event, a medicine reminder, water intake reminder, physiotherapy/exercise reminder.
Create a NotificationManagerClass to handle and schedule Local Notifications
We will use LocalNotificationManager
class to help us manage & schedule local notifications.
Here’s the starting definition of the LocalNotificationManager
class:
The class has one instance property called notifications
, of type [LocalNotification].
Now We’ll define that LocalNotification
type :
This LocalNotification struct will help us organize the notifications in a better way.
In above struct,
- id is used to identify unique notifications.
- title to get displayed as part of local notification.
- subtitle to get displayed as part of local notification.
- datetime is for the time when we want to schedule the notifications.
- repeats will be used to make it recurring or not.
User’s Permission to Send Local Notifications
Before we schedule local notifications, we need to ask for user’s permission. Asking permission to send local notifications involves the requestAuthorization(options:completionHandler:)
function of a shared UNUserNotificationCenter
instance. This singleton instance is used to manage everything related to notifications in our iOS app.
Write the below mentioned function inside LocalNotificationManager Class.
Below mentioned is what happens inside the function:
- First, we’re accessing the shared instace of
UNUserNotificationCenter
by calling thecurrent()
function. That way we get access to the single object that manages notifications on iOS. - Then, the function
requestAuthorization(options:completionHandler:)
is called which prompts the permission dialog. The parameter options is asking permission to display alerts, to change an app icon’s badge number, and to play a sound when the notification alert pops up. - Then, as the last parameter completion handler gets executed. It has two parameters,
granted
of typeBool
, anderror
of typeError
. We can check if the permission has been given or not based on these parameters. - So this function asks the iPhone users for permission to send local notifications. If permission is given, the
scheduleLocalNotifications()
function is called. If permission isn’t given, or an error occurs, nothing happens.
Local Notification Permission Status
We can use below mentioned schedule()
function to start the local notification permissions and the scheduling of notifications.
- First, we’re accessing that shared
UNUserNotificationCenter
and calling thegetNotificationSettings(completionHandler:)
function. Here completion handler is executed when the settings have been received. - Then we have
authorizationStatus
of enum type UNAuthorizationStatus. It tell us if and what permission has been given.
.notDetermined
. If the authorization is not determined, it means we haven’t asked for permission before. So, we’ll ask for permission by calling therequestAuthorization()
function.- Authorized or provisional. If the value of
authorizationStatus
is.authorized
or.provisional
, it means we have (temporary) permission to schedule notifications. So, we’ll schedule notifications by callingscheduleNotifications()
. - In the case of
.denied
, we don’t do nothing.
We have to call scheduleNotifications()
at 2 places :
- If permission has not been given, so it’s asked, and
scheduleNotifications()
is called fromrequestAuthorization().
- If permission has been given before, so
scheduleNotifications()
is called directly from theschedule()
function.
Schedule Local Notifications
Below mentioned function iterates over the LocalNotification
objects in the notifications
array and schedules them for delivery in the future.
Here function iterates over the notifications
array with a for loop. Inside the loop, for every item in the array, this happens:
- Creating an object of type
UNMutableNotificationContent
. This object contains the content of the notification, such as its title, subtitle, sound, repeats and time. - Then, create an object of type
UNCalendarNotificationTrigger
. This object contains the trigger for the notification, such as a date and time. - Then, we’re creating an object of type
UNNotificationRequest
. This object combines the content and the trigger, together with a unique ID. Every notification needs a unique ID, which we can conveniently use to reschedule a local notification. - Finally, the
request
object is passed to theadd(request:completionHandler:)
function of the sharedUNUserNotificationCenter
instance. This schedules the local notification and then executes the completion handler. In this completion handler, we’re checking that no errors occurred.
Now that the LocalNotificationManager
class is complete, we can schedule notifications :
We can remove pending or delivered notifications using their ids in this way:
Handle Incoming Local Notifications
When we tap on a local notification, iOS app opens by default. This is perfect if you just want to use notifications to open the app, but what if we want to handle specific notifications in the app?
We can respond to local notifications in two ways:
- When the app isn’t running, i.e. it’s in the background or closed, using the delegate function
userNotificationCenter(_:didReceive:withCompletionHandler:)
- When the app is running and in the foreground, using the delegate function
userNotificationCenter(_:willPresent:withCompletionHandler:)
To handle local notifications, iOS app needs to register a delegate instance that conforms to the UNUserNotificationCenterDelegate
protocol before the app’s application(_:didFinishLaunchingWithOptions:)
function returns as mentioned below.
UNUserNotificationCenter.current().delegate = self
Below mentioned delegate function gets called when the app starts from a tapped notification:
The response
object contains all information about the notification. In the above code we’re using the local notification’s identifier to find out what notification was sent. In the app, we can respond to a notification by restoring the state of the app, or presenting UI, or by taking some action.
It’s important to call completionHandler()
when we are done. This closure is passed to the delegate function, and it should be called when we want to indicate to the system that we are done handling the notification.
If we’ve defined any custom actions for the local notification, the response
object will also contain information about that action.
iOS app can also receive local notifications while it’s running. We have to use a different delegate function to respond to these notifications, and we use that function to determine what happens with the notification:
The above code is similar to the delegate function that responds to non-foreground notifications. Again, we’re checking what local notification was triggered, and we’re executing the completionHandler
to indicate that handling the notification is done.
We can pass options from the UNNotificationPresentationOptions
struct to the completion handler, to indicate what we want iOS to do with the notification. The above code shows an alert to the user, and plays the notification’s sound. You can also silence the notification by passing an empty array, i.e. no options, like this: completionHandler([])
.
Note: Don’t forget to
import UserNotifications
.on top of theLocalNotificationManager class.
That’s all about Local Notifications with Swift.
Hope iOS Developers find this post useful. Please leave a comment if you have any questions or thoughts regarding the Local Notifications.
If you like this article, feel free to share it.
Thank you.