Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Launch app from INExtension in SiriKit

I want to use SiriKit to start a workout. Starting the workout requires opening the main app from the app extension.

The boilerplate that Apple provides for the INStartWorkoutIntentHandling handler is

func handle(startWorkout startWorkoutIntent: INStartWorkoutIntent, completion: (INStartWorkoutIntentResponse) -> Void) {
    let userActivity = NSUserActivity(activityType: NSStringFromClass(INStartWorkoutIntent))
    let response = INStartWorkoutIntentResponse(code: .success, userActivity: userActivity)
    completion(response)
}

How can I open my own app from here? Something like myapp://workout?action=start&name=pushups This answer doesn't seem relevant, as I don't have a UIViewController with a extensionContext property for this extension type.

Last related bit: For the other actions (pause, end) I’d prefer to not open the main app, but to simply pause the workout which is running in the main app. I could use a similar custom URL to pause it, but that would open up the app which is an extra unnecessary step. Any good way to tell the main app to take a specific action from the INExtension without opening the app?

like image 493
Tyler Sheaffer Avatar asked Jul 23 '16 03:07

Tyler Sheaffer


People also ask

What is Intents extension?

Adding an Intents app extension target provides the initial files you need to build your Intents extension and configures your Xcode project to build that extension and include it in your app's bundle. Open your existing app project in Xcode.

What are app Intents?

An intent allows you to start an activity in another app by describing a simple action you'd like to perform (such as "view a map" or "take a picture") in an Intent object.

What are Siri Intents?

The Intents and IntentsUI frameworks drive interactions that start with “Hey Siri…”, Shortcuts actions, and widget configuration. The system also incorporates intents and user activities your app donates into contextual suggestions in Maps, Calendar, Watch complications, widgets, and search results.


2 Answers

For me I was able to launch app like so:

let activity  = NSUserActivity(activityType: NSUserActivityTypeBrowsingWeb)
activity.webpageURL = URL(string: "https://mywebsite/...")        
completion(MyIntentResponse(code: .continueInApp, userActivity: activity))

Then this will get called in the AppDelegate

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
        if let url = userActivity.webpageURL {
            handleDeeplink(url)
        }
    }
    return false
}
like image 194
MendyK Avatar answered Oct 25 '22 11:10

MendyK


For posterity: turns out this was a phase-in of this functionality between Xcode 8 betas, it's been resolved in Xcode 8 beta 3. They added the .continueInApp code to INStartWorkoutIntentResponseCode in this version , but it wasn't there in Xcode 8 beta 2. This status code allows for the direct passing of NSUserActivity (no need to use a URL scheme).

like image 43
Tyler Sheaffer Avatar answered Oct 25 '22 11:10

Tyler Sheaffer