krish krish - 16 days ago 6
iOS Question

How to replace depreciated UILocalNotification and add UNNotificationAction in iOS 10

I have created a scheduled notification in ViewController.swift and need two actions to be added to this notification. One that says "Call", and the other that says "Cancel". How can I add these actions in ViewController.swift? Here is the part of the code that has the function for firing my notification in my ViewController.swift:

func notificationFires(){

let notification = UILocalNotification()
// 2
notification.soundName = UILocalNotificationDefaultSoundName
notification.fireDate = datePicker.date

// 3
if textField.text == "" {

notification.alertBody = "You have a call right now!"

}
else{

notification.alertBody = self.textField.text

}
// 4
notification.timeZone = NSTimeZone.default
// 5
// 6
notification.applicationIconBadgeNumber = 1
// 7
UIApplication.shared.scheduleLocalNotification(notification)



func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
print("Recived: notification")



if cancelled == true{
print("cancelled happened")

}
func cancelNotify(){
cancelled = true
UIApplication.shared.cancelAllLocalNotifications()
}
completionHandler(.newData)

}

}

Answer

I haven't used notifications in iOS 10 yet, so I went ahead and figured it out as a learning experience for myself, now I can pass it on to you.

UILocalNotification is depreciated in iOS 10 and replaced by the UserNotifications framework.

In your AppDelegate get authorization from the user to show notifications and set up the centers delegate with UNUserNotificationCenterDelegate:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    let center = UNUserNotificationCenter.current()
    center.delegate = self
    let options: UNAuthorizationOptions = [.alert, .sound];
    center.requestAuthorization(options: options) {
        (granted, error) in
        if !granted {
            print("Something went wrong")
        }
    }

    return true
}

Present the notification to the user:

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    // Play sound and show alert to the user
    completionHandler([.alert,.sound])
}

Handling the actions:

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

    // Determine the user action
    switch response.actionIdentifier {
    case UNNotificationDismissActionIdentifier:
        print("Dismiss Action")
    case UNNotificationDefaultActionIdentifier:
        print("Default")
    case "foo":
        print("foo")
    case "bar":
        print("bar")
    default:
        print("Unknown action")
    }
    completionHandler()
}

Do this wherever you want to setup all actions and categories for all notifications in your app. Because they're assigned to the center, not the notification itself:

func setupActions() {

    //create first action
    let foo = UNNotificationAction(
        identifier: "foo",
        title: "foo"
    )

    //create second action
    let bar = UNNotificationAction(
        identifier: "bar",
        title: "bar",
        options: [.destructive]
    )

    //put the two actions into a category and give it an identifier
    let cat = UNNotificationCategory(
        identifier: "cat",
        actions: [foo, bar],
        intentIdentifiers: []
    )

    //add the category to the notification center
    UNUserNotificationCenter.current().setNotificationCategories([cat])
}

And finally creating the actual notification:

func setupNotification() {

    let content = UNMutableNotificationContent()

    content.title = "Hello!"
    content.body = "A message"
    content.sound = UNNotificationSound.default()

    //make sure to assign the correct category identifier
    content.categoryIdentifier = "cat"

    // Deliver the notification in five seconds.
    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
    let request = UNNotificationRequest(identifier: "hello", content: content, trigger: trigger)
    let center = UNUserNotificationCenter.current()

    center.add(request) { (error : Error?) in
        if let theError = error {
            print("theError \(theError)")
        }
    }
}

Be sure to import UserNotifications in each class utilizing these functions.

More info: User Notifications documentation.

Comments