There are two categories of notifications on iOS devices. One type is a push notification sent by a server, and the other is a local notification scheduled on-device that appears at a particular time or location.
This tutorial focuses on local notifications. An example of a local notification can be seen in your calendar. You add an appointment, set it to remind you 15 minutes before, and 15 minutes before the meeting begins, you see a notification on your lock screen. Let’s take a look at how these work.
User Notifications Framework
Apple provides the User Notifications framework to allow you to present a notification on a device. Unlike a remote notification that originates from a server, a local notification requires that you set a time based or location-based trigger.
For this project, we’re going to set up a SwiftUI project, although the code and concepts are primarily transferable to a storyboard based app.
Create a new SwiftUI project. You need to add a development team to the project in the Signing & Capabilities section for the app target. When ready, you can start building your view.
var body: some View {
VStack {
Text("Local Notification Test")
.font(.largeTitle)
.padding(.bottom, 40.0)
HStack {
Text("Calendar Entry:")
.padding(.leading)
TextField("Title", text: $calendarEntryTitle)
}
DatePicker(selection: $selectedDateTime, label: { Text("")
.multilineTextAlignment(.trailing)
.padding(.leading) })
.padding(.trailing)
.datePickerStyle(.wheel)
Button("Schedule Notification") {
// Work will be done here.
}
.padding(.top)
}
}
The code above makes a simple UI that we can use. It is arranged in a Vertical Stack with Text at the top as defined in lines 3-5.
Following the Text, there’s a Horizontal Stack on lines 7-11 that contains Text on the left and a TextField on the right.
Below the HStack, there’s a DatePicker on lines 13-17. The style is set to .wheel which is the older type. Removing line 17 will put it back as the newer iOS default. Feel free to adjust this if needed.
Lines 19-22 contain a button with the text “Scheduled Notification” set. This is the button we will use to trigger the local notification.
You will notice some errors in code because to get it working requires that some private vars are set with the @State property wrapper. You can add these properties just above the block of code above:
@State private var calendarEntryTitle: String = ""
@State private var selectedDateTime = Date()
The first one is used to store the value entered in the text field. The second one will contain the date when selected with the DatePicker.
Requesting Permission from the User
Sending notifications requires that you request authorisation from the user. This code is somewhat boilerplate to get it working, although you can tweak it to suit your own needs.
In the code block above, please insert the following on line 20 (where it says // Work will be done here). When the user taps to schedule a notification, it will seek permission from the user on the first attempt. Make sure you approve it at this point, or your notifications won’t appear when we trigger them later.
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
if let error = error {
// Handle the error here.
}
}
The code is relatively simple to understand. On line 2, we request authorisation from the user and indicate that we want to alert them with a sound and update the badge number on the app icon. If there’s an error, we can handle it, and if not, we’re good to send. Authorisation can only be requested once for an app. When this method is called again, it will skip over prompting you.
The next step is building the notification. We can use the following code for this:
let content = UNMutableNotificationContent()
content.title = calendarEntryTitle
content.body = selectedDateTime.description
UNMutableNotificationContent is required here and is what we use to compose the notification we want to trigger. On line 2, I set the title to what is stored in the @state property wrapper for calendarEntryTitle, and the body contains a string for the date/time used to trigger the notification.
The next step is to convert the Date object into DateComponents which can be used to create a trigger. We do that with the following code:
var dateComponents = DateComponents()
dateComponents = Calendar.current.dateComponents([.hour, .day, .minute], from: selectedDateTime)
Line 2, we set dateComponents to the hour, minute, and day of the selectedDateTime property, set when scrolling the wheels on the date picker.
let trigger = UNCalendarNotificationTrigger(
dateMatching: dateComponents, repeats: false)
let uuidString = UUID().uuidString
let request = UNNotificationRequest(identifier: uuidString,
content: content, trigger: trigger)
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.add(request) { (error) in
if error != nil {
// Handle any errors.
}
}
The code above shows how we create the trigger, get a unique identifier, create the request, and then add that request to the Notification Center.
Lines 1 and 2, we create a UNCalendarNotificationTrigger and pass in the date components object that we created. We do not want this particular notification to repeat, so we set that property to false. This type of trigger is not the only one you can create. Apple provides various kinds of triggers for notifications. One example is the UNLocationNotificationTrigger, which can detect when you enter or exit a specified geographical area.
Lines 4 and 5, we create a UUID (universally unique ID) and then create a UNNotificationRequest with the identifier set to the generated UUID. We pass in the content and also pass in the trigger.
On lines 8-13, we get the current UNUserNotificationCenter and add in the request created on line 5.
When you run the app on your phone, you will now be able to set the day and time with the DatePicker, set a title message, and then schedule the notification. Closeout the app, and your notification will trigger.
Conclusion
Local notifications have many uses beyond what was demonstrated here. In the coming tutorials, we will cover enhancing the notifications and present other use cases and show what else local notifications can do. Still, if you want to experiment, the code above, much of it being boilerplate from the Apple Developer site, will get you going in the right direction.
The entire project can be downloaded from here.
Leave a Reply
You must be logged in to post a comment.