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?
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.
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.
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.
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
}
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With