Launch app from INExtension in SiriKit
Asked Answered
L

2

8

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?

Liquesce answered 23/7, 2016 at 3:3 Comment(1)
Apple has defined failureRequiringAppLaunch response code, which almost implies that this is not a valid use-case from Apple's perspective. Seems unreasonable to require the app extension to re-implement the core use-case of my app (e.g. workouts involve more than just audio). I'd like to have users able to say "Siri, start a 10 minute upper body workout from MY-APP" using my custom vocabulary, and it would just start the workout in the app.Liquesce
R
3

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
}
Rosewood answered 11/7, 2019 at 20:30 Comment(0)
L
2

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).

Liquesce answered 23/7, 2016 at 16:18 Comment(4)
By the way, if you intention is to have the user select the app, you don't need to go to the app to start. you can do it through SiriDibranchiate
Ended up doing .continueInApp because I want to show the workout with my adsDibranchiate
what to do if i want to open app from RideIntentExtension Handler ? I cant find .continueInApp type in rideIntentExtensionSpearing
@AshishPisey Did you find a way to open main app without using continueInApp?Waiver

© 2022 - 2024 — McMap. All rights reserved.