Tom Kraina
Tom Kraina

Reputation: 3699

SiriKit: How to set output property when intent is handled in the main app?

Context

I'm working on adding support for Siri Shortcuts (Intents?) to a non-trivial app. My main goal is to allow users to automatise some tasks within the app using Shortcuts.app.

I have defined MyIntent in the Intents.intentdefinition in the Intents Extension target, together with MyIntentResponse, which has an output property file: INFile.

Given the non-trivial nature of the app, I'm forwarding the intent from Intent Extension to the main app:

    func handle(intent: MyIntent, completion: @escaping (MyIntentResponse) -> Void) {
        // Can't handle the intent in the app extension yet, let the main app handle it
        let response = MyIntentResponse(code: .continueInApp, userActivity: nil)

        // TODO: How to update the response (with an output property) if the intent continues in the app?
        completion(response)
    }

Problem

Once the intent is forwarded to the app, the AppDelegate.application(_:continue:restorationHandler:) method is called with a user activity which also has the property interaction: INInteraction? set.

From the provided INInteraction I can get both the intent: INIntent and response: INIntentResponse to handle the intent accordingly.

What's missing, however, is a way how to communicate back to the Shortcuts.app about the result of the intent and provide the desired output property (file: INFile).

Question

Is there a way how to provide an intent response with an output property set if the intent is handled in the main app?

Details

Interestingly, there's a AppDelegate method that should handle this use case:

optional func application(_ application: UIApplication, 
                   handle intent: INIntent, 
        completionHandler: @escaping (INIntentResponse) -> Void)

And the documentation says:

An app with an Intents app extension can use this method to handle an intent directly, instead of handling it in the app extension. You might use this method to implement workflows that you cannot implement easily in your extension. For example, you might use it to start or manage a user's workout session. If your app is not running, SiriKit launches your app in the background so that the Siri interface remains active.

More info: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/2887573-application

In theory, it should be possible just to call the completionHandler with a newly instantiated MyIntentResponse which would have file property set correctly.

However, this method is never called. Instead, the above mentioned AppDelegate.application(_:continue:restorationHandler:) is called.

Upvotes: 3

Views: 2121

Answers (1)

FryAnEgg
FryAnEgg

Reputation: 493

If you use .handleInApp instead of .continueInApp in your Intents extension handle() function, then your app delegate's handleIntent() function will be called instead of the continue:restorationHandler() function. This will allow you to pass back INIntentResponse back to the extension in the completionHandler.

Upvotes: 0

Related Questions