; ;
Craft At WillowTree Logo
Content for craftspeople. By the craftspeople at WillowTree.
Engineering

WWDC - How to implement Siri Shortcuts for your app

Jonathan Witten
Software Engineer
June 11, 2018

In keeping with a broader theme at WWDC '18 of opening up functionality and access for third-party developers, Apple introduced Siri Shortcuts, which will allow developers to make their app discoverable, and there for suggestable, by Siri when making suggestions to users.

With voice assistant competition at an all time high, it shouldn’t be a surprise that Apple rolled out new Siri features at WWDC. While Siri has traditionally been restrictive towards anything but first-party apps, these new announcements have opened the doors wide open for all apps to take full advantage of its features. Siri’s limited set of intent domains is now open to customization for all types of actions. Consequently, app developers can now expose quick shortcuts for Siri to perform in their apps. This includes anything in an app that a user would do many times such as booking a hotel room, transferring money from their bank account, placing an order at a restaurant, etc. In addition to just exposing these actions, users can specify unique phrases to trigger Siri. By allowing the user to specify how and when to prompt a shortcut, voice commands can now become a central and customizable piece of an app’s user experience.

In addition to Shortcuts, Apple also announced increased integration into the types of suggestions Siri makes to users. Siri will periodically make suggestions based on the patterns of actions that an app exposes. By specifying common intents whenever an action is performed, apps can inform Siri on what is the most appropriate action to suggest at any given time. This is another powerful opportunity for providing users with customized experiences.

To figure out how this all works, let’s look at an example: a banking app that allows Siri to transfer money between accounts.

Custom Intents

Custom Intents now allow apps to define their own models for requests and responses to Siri that are specific to actions performed in the app. Now these actions aren’t constrained by Apple’s system domain of intents.

Create an Intents Extension, which will be the extension that runs when your app handles requests from Siri

  • By default, an Intents Extension also creates an Intents UI Extension where you can define a view controller that Siri will show as an embedded view when processing your intent
image3

Create a new Siri Intents Definition file

  • Previously an app’s intent could only handle a limited set of intents that Apple defined. These included sending a message, making a call, requesting a ride, making a payment, etc.
  • This is a new file type which helps to define the model of an app’s intent
  • Now we can create a new custom type of intent, such as transferring money from a bank account
  • There are two parts to a custom Siri Intent:

1. Intent: defines the parameters that the user will provide to Siri.

image1

Give these a variable name and a type that you can use other areas of the intents model file. In our scenario the input parameters would be the account the user is requesting from, the account that is being transferred to, and the amount of the transfer. Specify which combination of parameters are valid in the “Shortcut Types” section of the model file.

2. Response: defines how Siri should respond to the intent after handling the request.

image2

Declare properties and their types in the model file to be used in the response, and define templates for Siri to respond with when either a success or a failure occurs.

The Intent Model

The Intent Model file will generate code for a couple of classes and a protocol: TransferMoneyIntent and TransferMoneyIntentResponse. These represent the user’s request and how the app will respond after processing the intent.

TransferMoneyIntentHandling

Implement this protocol in the app extension to confirm a user’s intent and then handle the request.

public class TransferMoneyIntentHandler: NSObject, TransferMoneyIntentHandling {
    
    public func confirm(intent: TransferMoneyIntent, completion: @escaping (TransferMoneyIntentResponse) -> Void) {
        
        // Do some validation on the Intent Request
        guard let amount = intent.amount?.amount?.decimalValue,
            amount > 0 else {
                completion(TransferMoneyIntentResponse(code: .failure, userActivity: nil))
                return
        }
        
        completion(TransferMoneyIntentResponse(code: .success, userActivity: nil))
    }
    
    public func handle(intent: TransferMoneyIntent, completion: @escaping (TransferMoneyIntentResponse) -> Void) {
        
        guard let from = intent.fromAccount,
            let to = intent.toAccount,
            let amount = intent.amount?.amount?.decimalValue else {
                completion(TransferMoneyIntentResponse(code: .failure, userActivity: nil))
        }
        // Do some work for the action
        TransferHandler().makeTransfer(from: from, to: to, amount: amount)
        completion(TransferMoneyIntentResponse(code: .success(amount: String(amount), toAccount: to), userActivity: nil))
    }
}

When implementing these functions, call the completion handler with one of the response codes unspecified, ready, continueInApp, inProgress, success, failure, failureRequiringAppLaunch This let’s Siri know which response (defined in the Intent Model file) to use.

Some Important Notes:

  • Make sure that the Intent Model file is included in the Intent App Extension.
  • Always implement the following in your AppDelegate because the user can tap on the shortcut and Siri will open the app with this method:
func application(_ application: UIApplication,
         continue userActivity: NSUserActivity,
         restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool

Shortcut Phrases

Apps now have the opportunity to prompt the user to define a custom invocation string for a specific shortcut. This allows users to put an apps actions into their own vocabulary, creating a personable and intuitive interface. Present a INUIAddVoiceShortcutViewController to prompt the user for a custom shortcut statement. This view controller takes a INShortcut object that represents the shortcut to be configured. After the user configures the shortcut with a custom statement, they can view it in My Shortcuts in the Settings App under Siri.

Siri Suggestions - Donating Intents

“Donating” an Intent means providing Siri with the information it needs to make a suggestion for an action that the user just completed. Siri will look for patterns in a user’s donated intents and will periodically attempt to provide a relevant suggestion. By defining different parameter combinations for the custom intent, Siri is able to look at trends in those donated intents and corresponding combinations to make a good suggestion. It is important to delete donated intents that include irrelevant information that the user has deleted from the app. If a user deletes a piece of data, they should not receive a suggestion that includes this information. Also, do not include actions that the user hasn’t performed and don’t donate intents for shortcuts while they are being handled in the Siri Intent Extension. INInteraction encapsulates the information that Siri needs to suggest an Intent. After a user completes an action, the app can create this object and then donate it. Here is an example of donating TransferMoney intent in the earlier example after a transfer has been made in the app:

func makeTransfer(from sender: String, to receiver: String, amount: Decimal) {
        let intent = TransferMoneyIntent()
        intent.amount = INCurrencyAmount(amount: NSDecimalNumber(decimal: amount), currencyCode: "USD")
        intent.fromAccount = sender
        intent.toAccount = receiver
        let interaction = INInteraction(intent: intent, response: nil)
        interaction.donate { error in
            guard error == nil else {
                print("Could not donate the intent")
                return
            }
            print("Successcully donated the intent!")
        }
    }

Relevant Shortcuts

In addition to donating Intents that the user has performed, apps can now share customizable relevant shortcuts for Siri to recommend at appropriate times in the future. This means apps can attach information about when or where this action might be useful to recommend. Apps can specify if this shortcut should be recommended while at the gym, or at home, or during the morning or evening.

  1. Create an INRelevantShortcut object with an INShortcut instance.
  2. Then, use the relavanceProviders property to assign an array of INRelevanceProvider values.
  3. Then get the INRelevantShortcutStore and call setRelevantShortcuts to make Siri aware of the actions that the app can perform. Here is an example using our scenario as before, but maybe the banking app wants to recommend a transfer every evening:
    func makeTransfer(from sender: String, to receiver: String, amount: Decimal) {
        let intent = TransferMoneyIntent()
        intent.amount = INCurrencyAmount(amount: NSDecimalNumber(decimal: amount), currencyCode: "USD")
        intent.fromAccount = sender
        intent.toAccount = receiver
        guard let shortcut = INShortcut(intent: intent) else {
            return
        }
        let relevantShortcut = INRelevantShortcut(shortcut: shortcut)
        relevantShortcut.relevanceProviders = [INDailyRoutineRelevanceProvider(situation: .evening)]
        INRelevantShortcutStore.default.setRelevantShortcuts([relevantShortcut], completionHandler: nil)
    }

Shortcuts App

In addition to invoking a custom shortcut with a unique phrase, users can also utilize these custom shortcuts in a new first party “Shortcuts” app. This app allows users to chain actions together and invoke them all with a single phrase. Now when apps allow users to create shortcuts they are offering an opportunity to use their app’s most important functionality in junction with other apps in a completely customizable way. Users can now transfer allowance money to their child’s bank account, send a text to their kid letting them know, and mark the task off their todo list, all with one voice command. The new improvements to Siri have opened the doors wide open to creating customizable, unique, and useful voice experiences.

Jonathan Witten
Software Engineer

Recent Articles

Engineering
.
Building Scalable White-Label Android Apps
Sean Kenkeremath
Engineering
.
Text Searching with MongoDB
Matthew O'Connell