UserNotifications Example I – Time Interval Trigger

9 minutes, 29 seconds

On this example we will trigger a notification based on time interval.

User Notification is a brand new framework for iOS 10. It evolve from traditional notification API which handles by UIApplicationDelegate.

There are 4 ways to trigger notification:

  • Time Interval
  • Calendar
  • Geofence
  • Push Notification (require server)

On this example we will discuss on how to schedule a notification using time interval.

Step-by-Step : User Notifications with Time Interval

We will go step by step how to use UserNotification framework.

  1. Authorization
  2. Content Creation
  3. Scheduling notifications with Time Interval
  4. Configure to show notification in-app
  5. Adding a Reminder Using Notification Actions

0. Import The Framework

For every view controller class that you want to use this framework make sure you import it at the top of the file.


import UserNotifications

1. Authorization

Before you ever schedule a notification to the user, make sure you ask permission first. ?

Add this code inside viewDidLoad() before closing bracket.


UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge])
{ (granted, error) in 
    // Enable or disable features based on authorization. 
}

Pro Tips: consider to ask the permission not at the first openning the app, but rather after you explain why or purpose of the notification. Notification authorization doesn’t need Info.plist usage string.

You also need to the current permission for notification, because users can change any time at Settings app. You may want to call this before you want to schedule a notification.


UNUserNotificationCenter.current().getNotificationSettings { (settings : UNNotificationSettings) in
  if settings.authorizationStatus == .authorized {
    // Still authorized
  }{
    // Not anymore
  }
}

2. Content Creation

We have to prepare first the content of the notification we want to display.

Lets write the content like the notification above. For the image make sure you have an image copied into the project’s directory, not app asset. For this example name the image is “swift.png”.

Attachment can be various of kind: image, sound, video and gifs.


// Notification Content Creation
let content = UNMutableNotificationContent()
content.title = "Title"
content.subtitle = "Subtitle"
content.body = "This is an example of body text, this should be a sentence long."
content.sound = UNNotificationSound.default()
content.badge = (UIApplication.shared.applicationIconBadgeNumber + 1) as NSNumber; // Always Increment!
content.categoryIdentifier = "notification-category" // For Actionable notification
//content.threadIdentifier = "notification-thread" // For collapsing the similar notif 

// Add the image as attachment
if let path = Bundle.main.path(forResource:"swift", ofType:"png") {
  let url = URL(fileURLWithPath: path)
  do {
    let attachment = try UNNotificationAttachment(identifier: "logo", url: url, options: .none)
    content.attachments = [attachment]
  } catch {
    print("The attachment was not loaded.")
  }
}

Wait, we just created the content only, the notification will not being shown yet. Lets know how should we show the notification banner.

3. Scheduling notifications with Time Interval

We will use time interval schedule notification for this example. Time interval use how many second from now to be notified.


// Deliver the notification in five seconds.
let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval:5, repeats: false)

If you want to make it repeating make sure time interval is at least 60 seconds.

This is the climax of the code, where the all the content, schedule will be put inside into a request, then add to the app’s User Notification Center to show the notification when the app is closed.

In-app notification also possible by configuring delegate and handle it appropriately.

Add this code to add the notification request into the OS.


// Schedule the notification
let request = UNNotificationRequest.init(identifier: "id-123", content: content, trigger: trigger)
let center = UNUserNotificationCenter.current()
center.add(request)

Here is the complete code to trigger a notification after you have authorized for notification. After trigger this code, close the app to make the notification show up.


@IBAction func trigger(_ sender: AnyObject) {
  
  let content = UNMutableNotificationContent()
  content.title = "Title"
  content.subtitle = "Subtitle"
  content.body = "This is an example of body text, this should be a sentence long."
  content.sound = UNNotificationSound.default()
  content.badge = (UIApplication.shared.applicationIconBadgeNumber + 1) as NSNumber;
  content.categoryIdentifier = "notification-category"
  //content.threadIdentifier = "notification-thread"
  // Add the image as attachment
  if let path = Bundle.main.path(forResource:"swift", ofType:"png") {
    let url = URL(fileURLWithPath: path)
    do {
      let attachment = try UNNotificationAttachment(identifier: "image", url: url, options: .none)
      content.attachments = [attachment]
    } catch {
      print("The attachment was not loaded.")
    }
  }
  
  // Deliver the notification in five seconds.
  let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval:5, repeats: false)
  
  // Schedule the notification.
  let request = UNNotificationRequest.init(identifier: "id-123", content: content, trigger: trigger)
  let center = UNUserNotificationCenter.current()
  center.add(request)

}

If you have preloaded sound, you can use this code. Make sure you have the file like “alarm beep.aif” file inside the project.


content.sound = UNNotificationSound.init(named:"alarm beep.aif")

Trigger using IBAction, then go to Home (shift+command+h), wait for a few second before the notification banner will show up.

NOTIF

You also may want to swipe down to reveal the content of the notification.

Simulator Screen Shot 25 Oct, 2016, 3.28.18 AM.png

4. Configure to show notification in-app

Previously we have to close the app to see the notification, but now we want to see in-app.

Add these codes inside viewDidLoad() before closing bracket.


let current = UNUserNotificationCenter.current()
current.delegate = self

Also add this conformation declaration UNUserNotificationCenterDelegate.

Add this delegate’s implementation.


// MARK:- UNUserNotificationCenterDelegate
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
  // To show the banner in-app
  completionHandler([.badge, .alert, .sound])
}

Try to trigger the notification again. Walla, it will show inside the app.

IN-APP

5. Adding a Reminder Using Notification Actions

In addition just to get notified, we can add actionable to the notification.

Add this at the end inside viewDidLoad() function.


let action = UNNotificationAction(identifier: "remindLater", title: "Remind me later", options: [])

let category = UNNotificationCategory(identifier:"notification-category", actions: [action], intentIdentifiers: [], options: [])

// we set to handle this [category] which has has action and its identifier
UNUserNotificationCenter.current().setNotificationCategories([category])

Remember we have setted previous notification with identifier “notification-category” right? So if the notification showing with the same identifier, the system will also give option of the presetted actions for the category. It will show a button when we swipe down the notification.

IMG

How to handle when user tap on ‘Remind Me Later’? We will implement another delegate function as follows.

We have to check the action identifier match, then we can do something, like trigger new notification. Lastly we have to call completionHandler() to tell the system we have done with handling action notification.


// MARK:- UNUserNotificationCenterDelegate
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
  
  if response.actionIdentifier == "remindLater" {
    
    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
    
    let content = UNMutableNotificationContent()
    content.title = "Reminder"
    content.body = "After 5 seconds"
    content.sound = UNNotificationSound.default()
    let request = UNNotificationRequest(identifier: "reminder-id", content: content, trigger: trigger)

    UNUserNotificationCenter.current().add(request) {(error) in
      if let error = error {
        print("Error: \(error)")
      }
    }
  }
  completionHandler() // finished handling 
}

So you have it, after you tap on ‘Remind Me Later’, this new notification will show up.

AQWQ

What Next

We have discussed about notification using time interval trigger, and it useful to create notification for another few seconds or minutes. How about to schedule on specific date and time, and make them recurring. We will discuss on the next post.