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 :)

Quick Tip: Peeking into objects

Hi everyone!

Remember this post from way back about creating custom LLDB summaries for your objects so that you can conveniently inspect objects while debugging? Well the folks at Cupertino have been hard at work and have shipped an awesome feature with the new XCode 5.1 – “Debug Quick Look” which renders my previous post pretty much useless (and I mean useless in the sense that it is now a magnitude easier to accomplish something even better).

So basically this is how it works- You can now provide a visual “meaning” to objects you instantiate by implementing the following method:

- (id)debugQuickLookObject{
    //TODO: Return anything you want to see while debugging
}

Let’s take a look at the following example – I’ve created a data type that maps an NSString to a UIColor (don’t ask me why). It’s really easy to think of how you’d like this visualized for debugging purposes, so rather than seeing something like this:

{
   Coffee = "UIDeviceRGBColorSpace 0.6 0.4 0.2 1";
   Deep = "UIDeviceRGBColorSpace 0.5 0 0.5 1";
   Ocean = "UIDeviceRGBColorSpace 0 0 1 1";
   Tree = "UIDeviceRGBColorSpace 0 1 0 1";
}

…we can now use the debugQuickLookObject and see something like this:
Screen Shot 2014-02-08 at 6.50.37 PM
Here’s the code that is responsible for generating this wonder:

- (id)debugQuickLookObject
{
    NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] init];
    [self.theDict enumerateKeysAndObjectsUsingBlock:^(NSString *str, UIColor *color, BOOL *stop) {
        NSAttributedString *colorAttrStr = [[NSAttributedString alloc] initWithString:[str stringByAppendingString:@"\n"] attributes:@{NSForegroundColorAttributeName : color}];
        [attrStr appendAttributedString:colorAttrStr];
    }];
    return attrStr;
}

Now remember, this is code that actually runs while your process is paused so you want to:

  1. Run as little code as possible (creating a caching mechanism is recommended)
  2. Avoid changing your application’s internal state – anything that runs in the debugQuickLookObject method actually interacts with your application’s classes, instances and general state so don’t mess with anything (think of this as Marty avoiding his parents in Back to the Future).

The cool thing about this feature is that you can basically return anything that has visual representation (Strings, Attributed strings, images, bezier paths, views, urls, etc…) and see them while debugging. To access the provided quick look object, all you need to do is hover over the instance and click the little eye icon.

I can already think of dozens of places in my code where everyone collaborating with me could benefit from this visualization (including myself). Also, it would be nice to see this becoming a community thing – Developers writing open source projects could enrich documentation using custom quick looks and generally anyone could write quick looks for existing complex and hard-to-debug code.

The power of concurrency

Hi everyone, and welcome to Saturday night’s advanced session regarding concurrency in iOS.

We all know that some of Apple’s more powerful devices come equipped with multiple cores and we mostly just trust the operating system to utilize this advantage whenever possible, right? Well, turns out there are some cases where we need to explicitly tell the operating system – ‘hey, this code should be executed concurrently’ (iOS is great, but it’s not a magician). Today, we will discuss one of these cases – concurrent enumeration.

Let’s say we have a huge data collection of independent data points and that we wish to execute some heavy mathematical operation on each of them. Now the mathematical operation(s) we wish to apply on a single object is completely orthogonal to all other objects meaning – this is code that’s ideal for running concurrently between processor cores. The way to do this is to enumerate this data collection with the enumerateObjectsWithOptions:usingBlock: method, like so:

[[arr copy] enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSNumber *num, NSUInteger idx, BOOL *stop) {
    //Do some heavy mathematical stuff with 'num'
}];

Just to emphasise the performance gain in using this method rather than fast enumeration, check out the output of running a similar scenario on the iOS simulator (yes, that’s why you see 4 cores):

Using simple, fast enumeration:

Simple

Simple enumeration – takes about 5 seconds to run 10000 iterations. You can see that operations run on one core, while the others are simply kicking back with a beer.

 

Using block enumeration with the NSEnumerationConcurrent option:

Concurrent

Now THAT’S team spirit! About 0.5 seconds to run 1000000 iterations. Unbelievable performance gain.

 

That’s it for today! Hope you find creative, safe ways to use this technique and remember – with great power comes great responsibility, so don’t abuse this API by running things in parallel that shouldn’t.

The Capper

I’ve recently written a little handy utility that some might find useful. The main idea: helping programers and designers understand the idea of resizable images and calculate the correct cap insets for an image based on how you want it to look.

This is a stretched image without defining cap insets. Ewwww.

This is a stretched image without defining cap insets. Ewwww.

After playing around with the controls - viola! Also, you'll find all the code you need at the bottom.

After playing around with the controls – viola! Also, you’ll find all the code you need at the bottom.

Using this tool is pretty easy – download the XCode project from gitHub or CocoaControls, add the image you want to fiddle around with into the project and update the image’s name in Configuration.h

I know the name I chose kinda sounds like “The Crapper”. I only noticed it a moment before pushing to git. Screw you.

Enjoy!

Quick tip: Bridging the gap between ARC and MRR

Since ARC was introduced, more and more developers have seen the light and joined the hype – it’s less prone to human error, it saves us a lot of code and of course it reduces the headache associated with manual retain-release or ‘MRR’. Of course I believe that a good Objective-C developer needs to be familiar with MRR just as any of us were back in 2011, though I always encourage starting new projects with the “use ARC” checkbox ticked on.

One of my favorite benefits of the way ARC does things is that it won’t let you call methods that aren’t visible / defined in your code. This means that there are naturally many less run-time exceptions of the all time favorite “unrecognized selector sent to instance” kind:

Thanks ARC! How responsible of you to say so…

But things weren’t always this convenient. Objective-C is known to be the relaxed stoner neighbour of programming languages. It lets you pass virtually anything to anything else, doing all the work dynamically at runtime and giving you a false sense of security while you write your code. In the pre ARC era if you weren’t careful enough, your app would have the potential to crash more frequently than an airline in southeast Asia during monsoon season:

Hey man relax, I mean come on… what’s the worst that can happen? Hey are you gonna finish those fries?

So what if we are still stuck on MRR? What if we’re working on an old project or simply want to leave memory management to ourselves? Are we doomed to work with this inconvenient disadvantage? Nope. Just add “-Werror=objc-method-access” to your “warning flags” section in the target build settings and this specific warning will turn into an error. Enjoy!

App Review: Dots – A Game About Connecting (or being an addict)

I recently came across the phenomenon called “Dots” – one of the more addictive iPhone games I’ve had the chance to play. The main idea is simple: you have exactly 60 seconds to connect as many dots as you can by color. Sounds boring, right? Well, there are some special patterns, powerups and other features that make this a simply hypnotic experience.

The first time you open the app, you’ll get a chance to play a very unusual tutorial. I say unusual because you don’t exactly understand what’s going on and what you’re supposed to do. I found it pretty intuitive but I guess this can be regarded as a screening process for people who won’t get the game anyway.

After finishing the tutorial, you’ll find yourself smoothly transported to the main menu screen. Right away you’ll notice how smooth, bouncy and fun everything is – even when dealing with boring tasks such as toggling the sound on/off, or typing in your username.

IMG_2464

It’s pretty clear which button they want me to tap…

IMG_2465

So I’ll tap the other one. That will show them!

Once you start playing, there’s very little chance you won’t get hitched – the playability is amazing, the overall experience is smooth and addictive. Make dots disappear by connecting them, make them disappear even more by connecting squares, shrink, expand, freeze time and waste it too! Wonderful…

IMG_2469

IMG_2470

IMG_2467

Yay for you...

Yay for you… Now go back to work

It’s also apparent that these folks gave a lot of thought to the audio – the sounds are mellow, fun and create a wonderful ambience for the whole experience. As you play more and more, not only will you loose touch with your family and friends, but you’ll also gain “dots” – this is the currency used in the game to purchase powerups, such as this one:

IMG_2468

Sounds like an adequate name for fat people pants 

You can also see how other people are doing after each game or through the “High Scores” section in the main menu. While writing this post, my high score was 310 and the leaderboard  number one had 608 (OMG!!! How?? Probably sold his house to buy dots via in-app purchase).

So what makes this app a winner in my opinion?

1. Extremely clean, smooth and intuitive UI

2. Simple-to-grasp concept with a nice range of stuff to learn as you go along.

3. Perfect audio. You’ll understand when you hear it.

4. Beautiful animations

Download at your own risk here, don’t come to me when you realize you forgot to pick up the kids because you were too busy breaking your own record.

Quick Fix: Facebook release an iOS SDK update. Time for renovations.

Update: 

Looks like the people at Facebook are hard at work… a couple of weeks after writing this post, Facebook released yet another (pretty major) update to the SDK. Find out what you need to do here:

https://developers.facebook.com/docs/tutorial/iossdk/upgrading-from-3.2-to-3.5/

Since September 2012, Facebook has kept the iOS SDK on the down-low for some reason and the latest version of the SDK up until a few weeks ago was 3.1.1. This, in my opinion was a huge problem for developers that had to settle for a hybrid, half-baked SDK that used deprecated methods as a formal practice. For instance, in order to invoke facebook dialogs, you had to import the “Deprecated Headers” folder and utilize it’s methods. How lame.

Well, the good news is that 3.2 (and 3.2.1 following very shortly after) is out and it contains many improvements, better error handling and most importantly – uses blocks instead of delegation wherever it can. You will no longer find yourself importing the deprecated headers in order to open a web dialog and from now on you can use the new FBWebDialogs class to do your magic.

facebook__y_u_no____by_jaret246-d4arl9w

Natural response, I get it.

Alongside the SDK Facebook did some great work and released more useful tutorials to make sure the transition to the new SDK is smooth and clear:

I highly recommend taking a couple of hours to upgrade your code to support these API changes – you never know when deprecated methods will start breaking things…

Quick Fix: Icons that are things

I recently found some nice UI/UX related material available on Pinterest and amongst it I found some exquisite app icons (not necessarily belonging to actual published apps). I found it interesting that the ones that caught my eye the most were the ones that represent real objects (TV, notebook, flask, etc…) – these are the icons that leave an impression on you and make you remember where they are on your springboard.

Once you really dive in to the details you can really come to appreciate the work that went into every single one – the attention to details, the complex texture, simply amazing! For instance, look at the wooden texture on the blackboard icon. Also, look at the amount of detail on the cocktail umbrella:

595923-Casette-Tape 296804-Ice-Cream-Sandwich 926344- 746554-Chalkboard-Icon 49ers Contacts Nestle 59518 745081-Hd-Movies 911442-Pizza-App-Icon 571983-Fruit-Punch-iOS-App-Icon786866-Fc-Barcelona-Fan-Ios-Icon

More available on Pinterest

Quick Tip: UIAlertView with block callbacks

What bothers me

Now more than ever I find myself pondering over the question: “Why delegates? Why???”

Last time I found myself asking this was when I had to display some UIAlertViews in a project (though I really tend to stay away from them for UX reasons).

If you’ve had a little more than 10 days of experience in iOS development, you’ve probably already used these for either feedback to the user or as a way to get input from the user. Using it is pretty simple – you create an instance of the UIAlertView while assigning it a title, a message and titles for it’s button(s) and a delegate. Next, you call “show” and viola, it pops out:

Screen Shot 2013-01-31 at 11.30.17 PM

The problem starts when you want to handle the user’s action – if we’re only talking about a 1-button “OK” alert then this is a non-issue, but if there are multiple buttons here and you wish to handle the user’s action according to their choice – that’s where the spaghetti code is born.

Spaghettelegate (It is too a word!)

Now you’ll find yourself implementing yet another delegate method for when the user dismisses the alert. Won’t it go along nicely with all the other out-of-order methods and code in your class? Something like:

- (IBAction)okPressed:(id)sender {
    UIAlertView *nagAlert = [[UIAlertView alloc] initWithTitle:@"Are you sure" message:@"No, seriously are you sure??" delegate:self cancelButtonTitle:@"Not really" otherButtonTitles:@"Yes!", nil];
    [nagAlert show];
}

#pragma mark - SomeDelegate
...

#pragma mark - SomeOtherDelegate
...

#pragma mark - UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    switch (buttonIndex) {
        case 0:
            [self quitInRage];
            break;
        case 1:
            [self doSomethingNice];
            break;
        case 2:
            [self breakEverything];
            break;
        default:
            break;
    }
}

And what if you need to display more than one UIAlertView? Do you start tagging each instance when you create it and then check the tag when the delegate method is invoked? Pfff… please…

An elegant approach

The way I decided to get rid of this pattern (once and for all) is to create a block-friendly “UIBAlertView” class (B stands for Block or Brilliant or any other B-related word of your choice). So now creating, displaying and handling an alert is an all-in-one deal like so:

- (IBAction)activateAlert:(id)sender {
    UIBAlertView *alert = [[UIBAlertView alloc] initWithTitle:@"Yes, like this" message:@"What are you looking at?" cancelButtonTitle:@"Leave me alone" otherButtonTitles:@"Button 1",@"Button 2",nil];
    [alert showWithDismissHandler:^(NSInteger selectedIndex, BOOL didCancel) {
        if (didCancel) {
            NSLog(@"User cancelled");
            return;
        }
        switch (selectedIndex) {
            case 1:
                NSLog(@"1 selected");
                break;
            case 2:
                NSLog(@"2 selected");
                break;
            default:
                break;
        }
    }];
}

This is elegant because:
A. When an alert is dismissed, you know exactly which one it is.
B. You’re creating, activating and handling the dismissing of your alert in the same section of code.

The code is available on gitHub and featured in CocoaControls check it out.

Any comments, suggestions or different approaches will be hunted down and executed. Just kidding, suggest away :)

UX: There’s a control for that

During my first year at university, I remember my Java professor telling us something I’ll never forget and that still guides me to this day: “Someone already wrote it”. His philosophy was very strong on this – if you’re trying to tackle a general problem, there’s a very good chance that someone already did most of the work and there is probably an open source library that does what you need. That’s the beauty of object oriented programming: If you do things right, everything is modular, plug & play, reusable and it’s especially true when coding for iOS.

There are extremely talented people writing amazing open source code for iOS. You can interact with them on Stack Overflow, where they volunteer their time and experience to help us solve our problems. You can see things they’ve done by browsing GitHub repositories and you can find endless reusable and open source code via simple Google searches.

And there’s even a greater advantage here when discussing user experience. There are hundreds of controls out there, some are free to use under several restrictions and some are for sale, that (if used correctly) give you the chance to create some very creative user interfaces. If you haven’t already, I suggest you give them a try.

A great site for browsing these controls (my personal favorite) is cocoacontrols.com – you can browse iOS and Mac OS X controls by rating, recency or just by keywords. Some very good and popular controls there include:

MFSideMenu – as seen on Path, Facebook and many MANY more:

full-2

MFSideMenu

MBProgressHUD – Great class for displaying blocking activity indicators. You’ve probably run into these in a billion apps:

MBProgressHUD

MBProgressHUD

iCarousel – A very flexible, well written control for beautiful 3D browsing:

iCarousel

iCarousel

I strongly recommend you to browse some or all of the iOS controls that are available for purchase/download. Even if you don’t choose to reuse them (some may not be up to standard, I admit), they will definitely open your mind in terms of what you can do on iOS. Enjoy!

Follow

Get every new post delivered to your Inbox.