Ahead of Twin Cities Pride 2017, we decided to make some changes to our accompanying iOS app that would take advantage of new iPhone features. The Pride app serves as a guide for the festival and parade, and is written in Swift 3.0. One newly implemented feature is known as Home Screen Quick Actions. This feature gives users with an iPhone 6s or 7 the ability to “3D touch” an app icon on their home screen to use app shortcuts. We used this feature to show users shortcuts to the parade, events, and map pages of the app.
Static Versus Dynamic Actions
There are two types of quick actions: static and dynamic. Static actions for an app are defined in a project’s Info.list file, and don’t change. Dynamic actions, meanwhile, are defined at runtime and can change (based on user actions, for example). Although only static actions were needed for our purposes, we decided to implement our actions as dynamic to avoid the “stringly” nature of defining them in the Info.list file. This also allows us to implement dynamic, changing quick actions in the future.
ShortcutManager
We created a Swift struct named ShortcutManager
with just two methods:
func shortcutItems() -> [UIApplicationShortcutItem] func handle(shortcutItem: UIApplicationShortcutItem) -> Bool
The first method provides an array of our three UIApplicationShortcutItem
objects, and the second one is called from the app delegate when a user taps on a shortcut item. One UIApplicationShortcutItem
corresponds to a quick action. The second method changes tabs based on the identifier of the shortcut item.
Because our app still supports iOS 8.0 and home screen quick actions are exclusive to iOS 9 and above, the ShortcutManager
is declared to be available for iOS 9.0 and above only, by adding @available(iOS 9.0, *)
on a line above the class declaration.
An enum is used for the shortcut identifiers:
enum ShortcutIdentifier: String { case openMap case openEvents case openParade }
And a UIApplicationShortcutItem
is defined in shortcutItems()
as such:
UIApplicationShortcutItem(type: ShortcutIdentifier.openMap.rawValue, localizedTitle: "Map", localizedSubtitle: nil, icon: UIApplicationShortcutIcon(templateImageName: "map_icon"), userInfo: nil)
In the app delegate, the shortcut items are set like this:
if #available(iOS 9.0, *) { application.shortcutItems = ShortcutManager.sharedInstance.shortcutItems() }
Similar to @available(iOS 9.0, *)
earlier, using #available(iOS 9.0, *)
causes the code in the conditional block to run only if the device has iOS 9.0 or above.
Handling shortcut item selections happens like this:
@available(iOS 9.0, *) func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) { completionHandler(ShortcutManager.sharedInstance.handle(shortcutItem: shortcutItem)) }
With quick actions defined dynamically, we can display a quick action to access the next upcoming event or provide directions to the festival based on user location in future versions of the app.
Twin Cities Pride 2017 is available for iOS and can be downloaded here.