Notification with actions
October 7, 2015 Krupa Kadecha 5 Comments

Notifications are the way to get user’s attention or communicate with user even application is not running. Notifications are used to notify user about some event or actions, or just remind user for some important task.

From iOS 8 Apple introduce interesting improvement in Notification that is Notification Action. With this, user can directly interact with the application without even opening the application.

Let’s create a demo application that allow you to add tasks and schedule reminder for that particular task. Add notification action for done task, remind me later and to add new task in the task list.

Note: To make it simple this example only works with Local Notification, you also can add Notification Action to push notification.

Step:1 Create a new project in xCode name it “Notifications Demo”.

Step:2 Register notification with Actions

Create a method name it registerNotification().

Now define notification actions, before it understand the notification actions, class used to define it and its property.

Notification Actions: Notification Actions defines the actions performed by user when notification arrives. Define Notification Actions using UIMutableUserNotificationAction class. This class provides various properties to configure actions.

Identifier: It is a string value that uniquely identifies the action among all other action in the application. It is useful to identify the action when user chose particular action when notification fire.

title: It is a string value that defines action title. Set appropriate title so, that user can easily identify the action performed by selecting it.

destructive: It is a bool value. When it set to true the action button display with red background. Generally it is used for deletion or any other critical actions.

authenticationRequired: It is a bool value. When it is true user have to authenticate himself to device before perform any action, that means user have to insert the unlock code to perform the action.

activationMode: It is an enum property. It defines whether the app should run in background or in foreground when the action performed.

In this demo application we are defining 3 notification actions in registerNotification() method, that is

  • Done task action
  • Remind me later action
  • Add new task action

// Clear all tasks
let doneAction = UIMutableUserNotificationAction()
doneAction.identifier = “DoneTask”
doneAction.title = "Done"
doneAction.activationMode = UIUserNotificationActivationMode.Background
doneAction.authenticationRequired = true
doneAction.destructive = false

// done particular task
let remindLaterAction = UIMutableUserNotificationAction()
remindLaterAction.identifier = “RemindLater”
remindLaterAction.title = "Remind in 5 mins"
remindLaterAction.activationMode = UIUserNotificationActivationMode.Background
remindLaterAction.authenticationRequired = true
remindLaterAction.destructive = true

// Add new Task
let addNewTaskAction = UIMutableUserNotificationAction()
addNewTaskAction.identifier =”AddNewTask”
addNewTaskAction.title = "Add New Task"
addNewTaskAction.activationMode = UIUserNotificationActivationMode.Foreground
addNewTaskAction.authenticationRequired = false
addNewTaskAction.destructive = false

Remind later and Done task action will be performed in background, but add new task action require to run the app in foreground so its activation mode is set to foreground.

Now after defining actions you have to group them together in a category. You have to define category if you want to add notification action in your notification. Define category using UIMutableUserNotificationCategory class and set category identifier using its identifier property. It has a method setActions(), It used to group actions together.

// Category
let taskCategory = UIMutableUserNotificationCategory()
taskCategory.identifier = categoryId

A. Set actions for the default context
taskCategory.setActions([doneAction, remindLaterAction, addNewTaskAction],
forContext: UIUserNotificationActionContext.Default)

B. Set actions for the minimal context
taskCategory.setActions([doneAction, remindLaterAction],
forContext: UIUserNotificationActionContext.Minimal)

Here, I have defined actions for default context and minimal context. Let understand what is default context and minimal context.

Default context: Default context refers to the alert, when your application accepts to display notification for your application as alert then all the actions grouped inside default context displayed as alert when notification fired (When device is unlocked).

Minimal context: Minimal context refers to the notification banner, when your application accepts to display notification for your application as banner or your device is locked then actions grouped inside minimal context is displayed. It does not show more than 2 actions.

Now define the type and other settings of notification and register it.

// 3. Notification Registration *****************************************

let types = UIUserNotificationType.Alert | UIUserNotificationType.Sound
let settings = UIUserNotificationSettings(forTypes: types, categories: NSSet(object: taskCategory) as Set)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)

Call this registerNotification() method from applicationDidFinishLaunching method in your AppDelegate.

Step:3 Create UI add new task and List all task

In your main.storyboard file add a textfield and a button that allows to add new task. When user tap add button ask to select date and time from date picker to schedule reminder for that task. Also list all added task below in a table view. Now after user add new task with reminder date and time schedule notification as below in your viewController class.


let notification = UILocalNotification()
notification.alertBody = "Hey, Have you completed your task?"
notification.soundName = UILocalNotificationDefaultSoundName
notification.fireDate = task.deadline // Date and time selected from DatePicker
notification.category = categoryId
// category id which you define at the time of defining category for notification actions.
notification.userInfo = ["title": task.title, "UUID": task.UUID]

UIApplication.sharedApplication().scheduleLocalNotification(notification)

Here, I have passed task.deadline in fireDate property.

task is object of model class Task, which have 3 properties that is deadline, title and UUID.

So that it’s easy to identify for which task the notification is fired.

Step:4 Handle notification Action

When notification fired handleActionWithIdentifier method will be called. You have to add that method inside your AppDelegate file.


func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) {
var task = Task(deadline: notification.fireDate!, title: notification.userInfo!["title"] as! String, UUID: notification.userInfo!["UUID"] as! String!)
if identifier == “DoneTask” {
NSNotificationCenter.defaultCenter().postNotificationName("DoneTaskNotification", object: task)
} else if identifier == “RemindLater” {
NSNotificationCenter.defaultCenter().postNotificationName("RemindLaterNotification", object: task)
} else {
NSNotificationCenter.defaultCenter().postNotificationName("AddNewTaskNotification", object: nil)
}
completionHandler()
}

In this method, I initialized Task class object with its property deadline, title and UUID.

You can get the deadline from firedate property of the notification, title and UUID can get from userInfo that is previously set at the time of scheduling the notification.

Now check which action is performed. You can check it using an identifier which you have set at the time of defining notification actions and perform a particular task.

I have posted different notification in notification center for different activities and passed Task class object to perform any action on a particular task.

Step:5 Add Observer for your notification center to handler notification action

Now you have added handleActionWithIdentifier method in your AppDelegate, it will post particular notification in notification center when any action performed. So, you have to add observer for that notifications.

Add Observer for notification center in your viewDidLoad() method.


NSNotificationCenter.defaultCenter().addObserver(self, selector: "doneTask:", name: "DoneTaskNotification", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "remindLaterTask:", name: "RemindLaterNotification", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "addNewTask:", name: "AddNewTaskNotification", object: nil)

Add selector for all the notification posted.

Add doneTask: selector for “DoneTaskNotification”

In that selector cancel local notification from that particular task object, remove that task from task list displayed.


func doneTask(notification: NSNotification) {
let task: Task = notification.object as! Task

// Remove notification for particular task
for notification in UIApplication.sharedApplication().scheduledLocalNotifications as! [UILocalNotification] { // loop through notifications...
if (notification.userInfo!["UUID"] as! String == task.UUID) { // ...and cancel the notification that corresponds to this TodoItem instance (matched by UUID)
UIApplication.sharedApplication().cancelLocalNotification(notification) // there should be a maximum of one match on UUID
break
}
}
// Remove particular item from Array
for (index, element) in enumerate(arrTaskLists) {
if element == task.title {
arrTaskLists.removeAtIndex(index)
}
}
tblTasks.reloadData()

// Change array of NSUserDefault
NSUserDefaults.standardUserDefaults().setObject(arrTaskLists, forKey: KEY_TASK_ARRAY)
NSUserDefaults.standardUserDefaults().synchronize()
}

Add remindLaterTask: selector for “RemindLaterNotification”

In that selector cancel local notification for particular task and schedule notification and set its fireDate after 5 mins.


func remindLaterTask(notification: NSNotification) {
let task: Task = notification.object as! Task

// Remove notification for particular task
for notification in UIApplication.sharedApplication().scheduledLocalNotifications as! [UILocalNotification] { // loop through notifications...
if (notification.userInfo!["UUID"] as! String == task.UUID) { // ...and cancel the notification that corresponds to this TodoItem instance (matched by UUID)
UIApplication.sharedApplication().cancelLocalNotification(notification) // there should be a maximum of one match on UUID
break
}
}

// Schedule notification after 5 mins
let notification = UILocalNotification()
notification.alertBody = "Hey, Have you completed your task?"
notification.soundName = UILocalNotificationDefaultSoundName
notification.fireDate = NSDate().dateByAddingTimeInterval(5 * 60)
notification.category = categoryId
notification.userInfo = ["title": task.title, "UUID": task.UUID]

UIApplication.sharedApplication().scheduleLocalNotification(notification)
}

Add addNewTask: selector for “AddNewTaskNotification”

This notification action’s activation mode is set to foreground so when this action fired your application is launched in foreground. So, to allow user to add new task just set your cursor to add task textfield by calling textfield’s becomeFirstResponder() method.


func addNewTask(notification: NSNotification) {
self.txtTask.becomeFirstResponder()
}

Summary:

All you have to done for interactive notification is

  • Define notification actions
  • Define category for both minimal and default context
  • Register notification.
  • Schedule notification for particular date and time.
  • handle notification action as per user’s selected action.

5 People reacted on this

  1. Hello! I just want to give a huge thumbs up for the nice data you may have right here on this post. I will probably be coming again to your weblog for extra soon.

  2. HI… Very informative post . Thanks for sharing. I am a mobile app developer So This will be really helpfulll for me in my future career. Good job that you have done. I really appreciate your work.

  3. Wow, amazing blog format! How long have you ever been blogging for? you make blogging look easy. The entire glance of your site is fantastic, as well as the content material!

Comments are closed.