Using notification actions

Hi guys! Sorry I was out of it for some time now, it was a pretty busy year so far.

I wanted to talk about a cool new feature available in iOS 8.0 – notification actions!

Once upon a push…

Up until iOS 7.0, whenever you got a remote notification while an app was in the background you could either:

A. Ignore it

B. Read it and ignore it

C. Read it and swipe / tap it

The third option would normally mean that the app gets relaunched and does whatever action it’s designated to do in that case (normally navigate to a certain screen in the app or do something general).

So what’s new?

Starting iOS 8.0, we have a fourth option:

D. Choose something to do from a menu

Think about the following scenario: You’ve created an awesome game that lets users around the world fight about nothing. Whenever someone challenges you to fight you should either respond with “Fight” or “Surrender”. Normally we’d present a notification to the user saying “dumdum86 has challenged you to fight about nothing” and you would need to open the notification by swiping (or tapping) and then choose either “Fight” or “Surrender” within the app. Luckily with the new notification actions we can let the user give us his input from the notification itself, which looks something like this:

Screen Shot 2014-08-30 at 4.14.32 PM

Note that the “Fight” and “Surrender” buttons appear to the user when he swipes the notification banner downward, otherwise the notification is simply standard text.

In the lock screen, the notification appears like it always had with one exception: you can now swipe to reveal actions:

 

Screen Shot 2014-08-30 at 4.17.14 PMScreen Shot 2014-08-30 at 4.17.11 PM

 

 

 

 

 

 

 

 

 

 

 

 

 

On a side note: If the user has chosen to display alerts from your app within an alert rather than a banner, he’ll see the message along with “close” and “options” buttons. If he taps “options”, he’ll see a second alert with the same message but this time with up to 4 options. When using the banners you can only show up to 2. For example – the following can be presented in an alert (the open and close options are added by the OS):

Screen Shot 2014-08-30 at 5.10.46 PM

Shut up and gimme teh codez!

The way to do this is to configure and register something called UIUserNotificationSettings. This class (available iOS 8.0 and up) is used to encapsulate the types of notifications that can be displayed to the user by the app. We will create 2 instances of a UIUserNotificationAction (one for fighting and one for surrendering), set them as actions within a UIMutableUserNotificationCategory which will be used for all “fighting” challenges and then add this category to our settings:


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    //1
    UIMutableUserNotificationAction *declineAction = [[UIMutableUserNotificationAction alloc] init];
    declineAction.identifier = @"REJECT_IDENTIFIER";
    declineAction.title = @"Surrender";
    declineAction.activationMode = UIUserNotificationActivationModeBackground;
    declineAction.destructive = NO;
    declineAction.authenticationRequired = NO;

    //2
    UIMutableUserNotificationAction *acceptAction = [[UIMutableUserNotificationAction alloc] init];
    acceptAction.identifier = @"ACCEPT_IDENTIFIER";
    acceptAction.title = @"Fight";
    acceptAction.activationMode = UIUserNotificationActivationModeForeground;
    acceptAction.destructive = NO;
    acceptAction.authenticationRequired = NO;

    //3
    UIMutableUserNotificationCategory *fightCategory = [[UIMutableUserNotificationCategory alloc] init];
    fightCategory.identifier = @"FIGHT_CATEGORY";
    [fightCategory setActions:@[declineAction,acceptAction] forContext:UIUserNotificationActionContextDefault];

    //4
    NSSet *categories = [NSSet setWithObjects:fightCategory, nil];
    UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:categories];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];

    // Override point for customization after application launch.
    return YES;
}

Here’s a breakdown of the above:

1 – Creation and configuration of an action for rejecting a fight. Note that the activationMode is set to “UIUserNotificationActivationModeBackground” – this specifies that the app doesn’t need to be foregrounded in order to respond to this action. (No need to bother the user if he isn’t up for a fight). The “destructive” property is NO because we don’t need the option to be highlighted as destructive and the “authenticationRequired” property is NO because we don’t need the user to enter his passcode to respond to this action.
2 – Creation and configuration of an action for accepting a fight. Note that the “UIUserNotificationActivationModeForeground” option specifies that the app needs to be launched in the foreground in order to respond to this action. This time “authenticationRequired” is YES because the user must unlock his device in order to play.
3 – Creation and configuration of a “fight” category used to encapsulate these actions. We use setActions:forContext: with the “UIUserNotificationActionContextMinimal” context, allowing us to show up to 4 options when displaying an alert (not a banner). If we also wish to specify a minimal subset of these options for when the notification is displayed as a banner, we can also register part of the options as “UIUserNotificationActionContextMinimal”.
4 – Creation of a settings object that includes all of the above + registering these settings with the app.

Once we have registered these actions with our app, we’re ready to present notifications and respond to the actions if they are chosen. The way to do this is to implement one of the following methods in your App Delegate (depending on whether this is a remote or local notification):

1. application:handleActionWithIdentifier:forLocalNotification:completionHandler:
2. application:handleActionWithIdentifier:forRemoteNotification:completionHandler:

For the sake of simplicity (and my free time) let’s assume we’re working with local notifications only. Here’s an example of a valid implementation:

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler
{

    if ([identifier isEqualToString:@"ACCEPT_IDENTIFIER"])
    {
        [[FightManager sharedManager] fightLikeAnIdiot];
    }
    else if ([identifier isEqualToString:@"REJECT_IDENTIFIER"])
    {
        [[FightManager sharedManager] surrenderLikeABaby];
    }

    completionHandler();
}

 

* Note: According to Apple’s docs you must call the completion handler at the end of your method. So do it. Because Apple.

Great, now all that’s left to do is call a notification in order to demonstrate our new feature:

- (IBAction)someButtonPressed:(id)sender
{
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.fireDate = [NSDate dateWithTimeInterval:10.0 sinceDate:[NSDate date]];
    notification.category = @"FIGHT_CATEGORY";
    notification.alertBody = @"dumdum86 has challenged you to fight about nothing.";
    [[UIApplication sharedApplication] scheduleLocalNotification:notification];
}

 

The above code responds to a tap of a button, creates a local notification that’s scheduled to fire in 10 seconds and presents the message shown at the begging of the post. The category identifier must be the same FIGHT_CATEGORY previously specified when registering the actions with the app. Of course this is just for demonstration purposes so everything in there is hard-coded.

That’s it! Theres much more to play around with but the main idea should be enough to get you started. Enjoy 🙂

Advertisements

Posted on August 30, 2014, in UX. Bookmark the permalink. 6 Comments.

  1. Very helpful example – thank you!

  2. This is great. Seen any documentation on how to do an in-line comment, like Messages is doing?

    • There is currently no open API to achieving this. Apple likes to keep some killer features exclusive so that it has the upper hand. This is an example of one of these cases.

  3. thank you, very helpful for me,i want to know except the UIMutableUserNotificationAction look like, can it be look like imessage’s quick reply

    • Like I told sdrosen, there is currently no way to achieve the iMessages style quick reply as there is no API for this. You’ll need to work with a “Reply” button that opens your app with a text field ready to go.

Say something...

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: