I’m currently working on my third iOS app using Swift and I needed to add scheduled local notifications for one of the main features so, after struggling to get notifications to work, I decided to make this simple tutorial.

1 - Request user authorization

To be able to present local notifications to our users, we’ll need to ask them for authorization first. Go to your AppDelegate and add the following code:


class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    let notifCenter = UNUserNotificationCenter.current()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            // your app launch code here
        
            requestAuthForLocalNotifications()
        
            return true
        }

    func requestAuthForLocalNotifications() {
        notifCenter.delegate = self
        notifCenter.requestAuthorization(options: [.alert, .sound]) { (granted, error) in                
            if error != nil {
                // Something went wrong
            }
        }
    }
}

2 - Schedule a new local notification

Let’s say we have a UIButton in one of our UIViewControllers and we want to schedule a new local notification that will be shown in 7 days from now. We’ll need to create the following components:

  • Content: You’ll need to define which information will be included in your notification.
  • Trigger: You must define when the notification will be displayed.
  • Request: Will combine the content and the trigger to create a notification request.
@objc func buttonTapped(_ sender: UITapGestureRecognizer) {
    scheduleLocalNotification()
}

func scheduleLocalNotification() {
    let content = UNMutableNotificationContent()
    content.title = "The title of your local notification"
    content.body = "A long description of your notification"
    content.sound = UNNotificationSound.default
        
    // You can use the user info array if you need to include additional information in your local notification.
    // Then you could use that additional information to perform any kind of action when the notification is opened by the user
    content.userInfo = ["CustomData": "You will be able to include any kind of information here"]
        
    let yourDate = Calendar.current.date(byAdding: .day, value: 7, to: Date())!
        
    let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: yourDate.timeIntervalSinceNow, repeats: false)
        
    let request = UNNotificationRequest.init(identifier: "your-notification-identifier", content: content, trigger: trigger)
        
    let center = UNUserNotificationCenter.current()
    center.add(request)
}

3 - Allow local notifications in foreground

By default, local notifications will only be displayed if the app is in the background. If you want to be sure your scheduled notification is presented to your user, add the following function to your AppDelegate:

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    completionHandler(UNNotificationPresentationOptions.init(arrayLiteral: [.alert, .badge]))
}

4 - Handling user interaction with the notification

After adding the following function to your AppDelegate, you’ll be able to perform a custom action when the user opens your local notification.

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {        
    if let customData = response.notification.request.content.userInfo["CustomData"] as? String {
        let homeVC = window?.rootViewController?.children[0] as? HomeVC
        homeVC?.notificationTappedWith(customData: customData)
    }
}

That’s it! With these 4 simple steps, you’ll be able to show local notifications in your app.

If I’m missing something, please let me know in the comments below! 👇

This post is also available on DEV.