The first thing I'm going to talk about are Quick Actions. If you happen to own an iPhone 6S, you may have noticed that when pressing hard on an app icon, you see a little menu like this pop up:

Neat little shortcuts like this are the exact reason why I love Apple products. Personally I can think of a thousand ways one would use these and frankly, I believe every app can benefit from including these in their app. So without further ado, the following should teach you how to make your app cooler. (Not that it wasn't already cool.)

Quick Actions

There are two types of Quick Actions: Static and Dynamic.

As you can probably surmise, Static Quick Actions are created once and generated at compile time. They even show up if the user has never opened up your app!

Dynamic Quick Actions however, have more flexibility and can be generated and deleted at runtime. However, they don't show up until the code to generate these actions is run. The user has to at minimum open your app before a Dynamic Quick Action shows up.

There are a couple of rules to keep in mind when creating these Static and Dynamic Quick Actions:

  • Static Quick Actions are top priority. They show up at the top of your Quick Action list and stay above your Dynamic Quick Actions.
  • You can only store up to 4 Quick Actions per app. This includes both Static and Dynamic Quick Actions put together. Since Static Quick Actions take higher priority, having 4 Static Quick Actions means you cannot have any Dynamic Quick Actions. If you have 1 Static Quick Action, then you can fit up to 3 Dynamic Quick Actions. Simple math, yo.

Creating the Icon for a Quick Action

All Quick Action items can have icons. Without them however, your Quick Action can potentially look very dull. (Re:
WILL
look dull). However, adding an icon to a Quick Action isn't as easy as it looks. One would expect for you to just supply a UIImage to a property or what have you but alas, this is not the case for Quick Actions. To supply an icon for your Quick Action, you actually need to use an instance of the UIApplicationShortcutIcon class.

The UIApplicationShortcutIcon class has no properties or functions. Just three initializers. And when the icon's are rendered, they are rendered as template images instead of full color.

Creating an instance of UIApplicationShortcutIcon isn't too difficult though. Here's some code that shows each of the three ways to initialize a UIApplicationShortcutIcon:

//Initialized with the UIApplicationShortcutIconType enum
let enumIcon = UIApplicationShortcutIcon(type: .Search)

//Initialized with a template image. Similar to UIImage
let suppliedImageIcon = UIApplicationShortcutIcon(templateImageName: "KrakenDevIcon")

The first way shown accepts an enum value from the UIApplicationShortcutIconType enum. All of the possible values that you can use are found here.

The second way shown accepts a templateImageName. Much like UIImage's imageWithName initializer, you need to make sure that you actually have an image in your Images.xcassets folder for this one to work.

The third way is by initializing with a CNContact (or a subclass of it) from Apple's new Contacts Framework. Icon's initialized this way are rendered fully colored!

import ContactsUI.UIApplicationShortcutIcon_Contacts

//Initialized with a CNContact
let store = CNContactStore()
let contacts = try store.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName("The Kraken"), keysToFetch:[CNContactGivenNameKey])
if let contact = contacts.first {
    let contactIcon = UIApplicationShortcutIcon(contact: contact)
}

If you use this way of initializing however, you MUST remember to import the ContactsUI framework in your project and put the import ContactsUI.UIApplicationShortcutIcon_Contacts at the top of the file you are creating your Shortcut Items. Without it, your app will quit with an "unrecognized selector sent to class" crash. Since this initializer also accepts CNMutableContacts, you would think that you could theoretically try to get around the non-color icon restriction. Perhaps, if you're like me, you would try to create a CNMutableContact, assign it some imageData, and then use that contact without having to save it to your address book.

Unfortunately, that doesn't work.

After an hour of hacking around that, I saw yet another rule in Apple's Developer Docs that said this:

You can, alternatively, pass in a CNContact object you create at runtime. Such a contact must have at least a first name or a last name. The quick action icon returned from this method is then a monogram built from the contact’s name. With this approach, it is not possible for you to provide an image for the quick action icon.

Well, so much for that. I shall be reading the docs first in the future.

Creating a Dynamic Quick Action

Out of the two types of Quick Actions, Dynamic Quick Actions are by far the easier ones to deal with. Granted you don't already have 4 Static Quick Actions, creating a Dynamic Quick Action only takes a couple lines of code. To create a Quick Action, you need to use an instance of UIApplicationShortcutItem by supplying a type and title at a minimum:

let shortcutItem = UIApplicationShortcutItem(type: "WhateverYouWant", localizedTitle: "Howdy Doo")

Of course, there is another initializer for UIApplicationShortcutItem and it accepts 5 parameters: type, localizedTitle, localizedSubtitle, icon, and userInfo. Let's break down what these are:

  • type - This is an app defined String and is required to create a UIApplicationShortcutItem. It can be anything you like but should generally be a String that can differentiate which Shortcut was selected by the user. I personally like to use a ShortcutType String enum for this. For example, in the Twitter App, we can assume they have a DM Type, a Tweet Type, and a Search Type for their Quick Actions.
  • localizedTitle - This is a user-facing String that is shown in Bold in the Quick Action list cell. This is also required to create a UIApplicationShortcutItem. Try to be as descriptive as possible while being short and sweet. And make sure to localize it! While it isn't required to be localized, you should make sure not to leave out foreign language speaking users. We all know how it feels to be left out. Think of your fellow human you nerd, you.
  • localizedSubtitle - This is also a user-facing String that is placed below the localizedTitle label in the Quick Action cell that you see on the home screen after activating the Quick Actions. This one is completely optional and be nil. Also make sure to localize this one too!
  • icon - This parameter accepts an instance of the UIApplicationShortcutIcon class (as explained above) and is also opt-in for the developer.
  • userInfo - This one is simply an opt-in plist-encodable dictionary that enables you to supply extra information about a shortcut such as a contact name, or even a music file's name and playback location. Do with this one what you will.

In order to actually add these Dynamic Quick Actions to the home screen, you need to maintain an array of shortcut items that you assign to UIApplication. Just execute this line of code...

UIApplication.sharedApplication().shortcutItems = [shortcutItem]

...and you are set to go!

You can update that array property however you wish. Delete at will or add to your heart's content. Just remember the golden rule: You can only have four of these babies at a time (That's also including any existing Static Quick Actions too).

Creating a Static Quick Action

This one is easy as well but not intuitive to create. To create a Static Quick Action, everything is done in the Info.plist file of your app. After learning about Dynamic Quick Actions, the keys that you need to use are pretty self explanatory. This is how a typical Static Quick Action looks like in your Info.list file:

As you can see, the structure inside of the plist is an array of dictionaries. For your convenience, you can copy and paste this code directly into your plist as a good starting template:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <dict>
        <key>UIApplicationShortcutItemIconType</key>
        <string>UIApplicationShortcutIconTypeSearch</string>
        <key>UIApplicationShortcutItemSubtitle</key>
        <string>shortcutSubtitle1</string>
        <key>UIApplicationShortcutItemTitle</key>
        <string>shortcutTitle1</string>
        <key>UIApplicationShortcutItemType</key>
        <string>$(PRODUCT_BUNDLE_IDENTIFIER).First</string>
        <key>UIApplicationShortcutItemUserInfo</key>
        <dict>
            <key>firstShorcutKey1</key>
            <string>firstShortcutKeyValue1</string>
        </dict>
    </dict>
</array>
</plist>

After you paste that, you have to rename the key of your new row to UIApplicationShortcutItems and voila! You have Static Quick Actions in your app! Each dictionary in the top level array of that entry correlates to one Static Quick Action. For your convenience, I'm going to list the different keys you can use to edit your Static Quick Action:

  • UIApplicationShortcutItemIconType - The value of this key correlates to the icon property of a UIApplicationShortcutItem. This particular key is equivalent to initializing a UIApplicationShortcutIcon with an enum value from the UIApplicationShortcutIconType enum. The value of this key correlates to the old Objective-C way of passing around enum values. Instead of putting in a value of .Search like you would in Swift, you need to list the enum type first followed by the enum value like so: UIApplicationShortcutIconTypeSearch.
  • UIApplicationShortcutItemIconFile - This key can be used instead of the previous UIApplicationShortcutItemIconType key if you have a custom image in your Images.xcassets folder that you want to use as the icon for your Static Quick Action. The value you put in should be the name of the image string as found in the Images.xcassets folder.
  • UIApplicationShortcutItemTitle - This directly correlates to the title property of a UIApplicationShortcutItem and accepts a String as the Value.
  • UIApplicationShortcutItemSubtitle - This directly correlates to the subtitle property of a UIApplicationShortcutItem and accepts a String as the Value. Pretty self-explanatory.
  • UIApplicationShortcutItemType - This correlates to the type property on UIApplicationShortcutItem and accepts a String as the Value. For more information on that, check the section above under "Creating Dynamic Quick Actions". I have a nice list that explains each property.
  • UIApplicationShortcutItemUserInfo - Much like the userInfo property that you can find in many APIs such as NSNotifications, this key accepts a dictionary as it's value. What you want to put in your userInfo dictionary is other information about your shortcut item that is plist encodable which are value types such as Arrays, Dictionaries, Booleans, Dates, Data, Numbers, and Strings.

Taking Action

So far we've talked about creating shortcut items. The next thing to learn is how to actually figure out when a shortcut item is tapped. Luckily enough, performing actions on shortcut items are super easy to implement. Much like Local Notifications, you need to track the event in your AppDelegate. Here is the function you want to implement in your AppDelegate:

func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: Bool -> Void) {
    //Here you are going to want to use the shortcutItem parameter.
}

Within that function, you are going to want to query the shortcutItem parameter's properties to figure out what to do next. You may have known it all along but here is where your type property is going to come in handy!

Using Swift to Make Performing Actions Easier

Since Swift has more powerful enums than Objective-C, I HIGHLY suggest that you use one when creating your shortcutItems. Since the type property is a String, I like to use a ShortcutItemType enum to figure out what action I will be taking on a particular shortcutItem:

enum ShortcutItemType: String {
case Release
case Capture
case DenyExistence
}

//create a shortcut item using our new enum
let shortcutItemNumbaOne = UIApplicationShortcutItem(type: ShortcutItemType.Release, localizedTitle: "Release the Kraken", localizedSubtitle: "Wreak havoc on your enemies.", icon: UIApplicationShortcutIcon(templateImageName: "KrakenDevIcon"), userInfo: nil)
let shortcutItemNumbaTwo = UIApplicationShortcutItem(type: ShortcutItemType.DenyExistence, localizedTitle: "Deny Its Existence", localizedSubtitle: "The Kraken can't be real, dudette.", icon: UIApplicationShortcutIcon(templateImageName: "KrakenDevIcon"), userInfo: nil)

//Assign it to our application's shortcutItems array
UIApplication.sharedApplication().shortcutItems = [shortcutItemNumbaOne, shortcutItemNumbaTwo]

//In our AppDelegate, we're gonna use our fancy new enum to figure out which shortcut item was selected!
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: Bool -> Void) {
if let itemType = ShortcutItemType(value: shortcutItem.type) {
switch itemType {
case .Release:
print("It's time. No denying it anymore. We MUST RELEASE THE KRAKEN")
case .DenyExistence:
print("Haha, sucker! The Kraken is real and he's going to eat you alive.")
case .Capture:
print("FOOL! There's no capturing the Kraken! Quiver in fear for you will be destroyed by the almighty Kraken!")
}
}
}


And that, my friend, is doing it right. I'm out, dog.

CONCLUSION

In the end, creating Quick Actions for your app is not actually that hard but it can be pretty difficult remembering all of the little intricacies that come with creating them. For the sake of making all of our lives easier, putting all of this information in one place should hopefully help you not have to wade through all of Apple's documentation. So far, I've enjoyed playing with 3D Touch and I hope you do too. And as always...

Happy coding fellow nerds!

KrakenDevIcon.png