Today I decided to start learning iOS programming. I've had a great experience with React Native, but some things are just nicer done native. This article covers local notifications, using UNUserNotificationCenter
. I'm using Swift 5, Xcode 11 and iOS 13.
This article was published on 07/10/2019.
Create a new Single Page app! That's it.
This app will use a very simple interface built using the new SwiftUI
. In ContentView.swift
, add the following:
https://gist.github.com/f4cf09398794e33acfd2e65a96e9a2d7
You should be able to preview this using the canvas
. If it is not shown, click "Help" and type "canvas". It looks like this:
This will let us set a notification by pressing a button. Let's move onto the main topic: UNUserNotificationCenter
. Create a new file, LocalNotificationManager.swift
, with some boilerplate code:
https://gist.github.com/1adcb2bdcf57d1261192dd8affa59bac
Now we will build four functions to handle the notification flow. We need to request permission to show notifications, then schedule some notifications.
Add a requestAuthorization
method. This will request permission to show notifications, and if permission is granted, then schedule any existing notifications the application has created.
https://gist.github.com/ae5c4a151739f089ea03b85f733e47bc
You can use the simulator or a real device to try this. You should see the following:
Next, let's make a method to add notifications. This will not schedule them - that comes later.
https://gist.github.com/0aed8c1953bb5b35bf730a9aa0493066
Simple stuff. We use a UUID
to ensure the id
is unique.
Now we have a way to request permission and to add some notifications - let's schedule them with a scheduleNotifications
function.
https://gist.github.com/370e41005eba96d7905e71feab36a094
There are few interesting things here. Firstly, we use UNMutableNotificationContent
. The rest of the code is modelled after the example from the Apple Developer docs. The name Mutable
suggests there is an Immutable
type - ther isn't. From what I gathered, the mutable here refers to the part of a UNNotification
that is mutable - that is, the content the developer is free to modify.
This example sets a notification to appear in 5 seconds. Other types of notifications include UNCalendarNotificationTriggger
. UNLocationNotificationTrigger
and UNPushNotificationTrigger
.
If you have a device, or use the simulator, you can try this out by updating the setNotification
function in ContentView.swift
:
https://gist.github.com/4960f008dbe0e1d9d36e49862f533070
Click on "Set Notification" and minimize the test app. After 5 seconds pass, you should see the notification! If you did not minimize the app, you will notice the notification does not show. We will address this later. Until iOS 12, notifications would not show if the app was in the foreground, however from iOS 12 you are able to show notifications in both the foreground and background. To do this, you need to add a bit of extra code in AppDelegate.swift
. When you extend a class using a delegate, you enable the class to hand off some behaviour to an instance of another type.
According to the docs, the UNUserNotificationCenterDelegate
is used to handle incoming notifications. We can use the userNotificationCenter(_:willPresent:withCompletionHandler:)
to "ask the delegate how to handle a notification that arrived while the app was running in the foreground". This is exactly what we need.
Update AppDelegate.swift
:
https://gist.github.com/e3272d1d69133654a8db67eeaff9503d
There are several changes:
- Add
UNUserNotificationCenterDelegate
to the class declaration - Add a
userNotificationCenter
function that calls thecompletionHandler
- Assign
UNUserNotificationCenter.current().delegate
toself
inapplication
Now you can press "Set Notification" and see a notification appear in-app.
We can improve the code a bit - namely, only ask for permission if we haven't already asked. Add a schedule
function to the LocalNotificationManager
class:
https://gist.github.com/74c6078d91828cc8e907b138d31c2b70
Now we don't need to know the authorization status - just call schedule
. Since we still want to schedule notifications after asking for permission, update requestPermission
:
https://gist.github.com/d57d812388c0281dd30c8fa34ba2e7a0
The final code for ContentView.swift
is now as follows:
https://gist.github.com/73db52a2006d1abc0496e66f09870707
This article introduces a number of things, including:
UNUserNotificationCenter
- SwiftUI (not the main focus, but still nice!)
- Using delegates, specifically the
UNUserNotificationCenterDelegate
- The
requestAuthorization
API