In watchOS 3.2, Apple includes support for SiriKit Intents. An Intents Extension allow apps to utilize Siri for a few things, including ride-hailing, sending messages, and… workouts! Now that it’s out on watch, it’s a fantastic opportunity for us to integrate with MySwimPro. Checkout the demo video below:
Implementing The Basics
After looking at the workout intents extensions, we decided to implement all of the workout commands: Start, Pause, Resume, Cancel, and End. We already had each of these abilities in the app, but we needed to hook them up to the calls from the intents extension.
See Also: Building MySwimPro For The Apple Watch
This turned out to be relatively easy. In our code, we keep a singleton (single reference) to the active workout session (if there is one) and call all of the action methods we need. By using a singleton, we have the added benefit of enforcing only one workout being started at a time.
The active interface controller listens for start/pause/resume/cancel/end events on the active workout session, and responds appropriately. Refactoring the app to respond to these events was the bulk of the work for implementing SiriKit. In the end it did result in cleaner code!
We also had to coordinate the different responses from the phone and the watch. The intents extension on the phone sends messages only to the phone app, so we had to relay them to the watch from there when necessary, and display an alert to the athlete so they know it was relayed.
Hey Siri, how long is this pool…?
A true challenge unique to SiriKit is getting the pool length from an Intents request. The SiriKit workouts intent isn’t customized to handle lap length input – an important input to calculating swimming distance for the watch. However it does have the ability to start workouts with goal values (time, distance, or calorie).
It turns out that when you say something like “Hey Siri, start a swim workout with MySwimPro for a 30 meter pool,” the intents extension picks it up as (approximately) “Start a workout with a 30 meter goal value.” Because we don’t support goal values (yet) we decided that swimmers are more likely to speak their pool length than say a goal distance.
Handling Bad Input
There are a few edge cases we needed to handle:
Incorrect pool length input (Siri misheard your distance request)
We added a countdown timer that gives you a few seconds to cancel the workout if you see that the pool length Siri recorded was incorrect.
Invalid pool length input
This is handled in the intents extension – we return an error response to Siri if someone tries to start a workout in an unsupported unit (i.e. minutes).
Starting a workout from a Series 0/1 watch
We return an error if someone tries to start a workout on a watch that doesn’t support swimming. This is harder to detect when someone starts a workout from the phone, so we are working on a solution for this.
Trying to pause/resume/cancel/end workout from phone
This was one of the more frustrating ones. It’s easy to start a workout, using `HKHealthStore().startWatchApp`, but because, in an intents extension, we can hold minimal state, it is difficult to spin up a connection to the watch using Watch Connectivity. Since Watch Connectivity is required to send messages to the watch, we just tell the athlete to check their watch (with an alert) in each of these cases from their phone.
The SiriKit extension can cover the following scenarios:
- Start pool workouts with no pool length given (use default length from app settings)
- Start pool workout with custom pool length given
- Start open water workout
- Pause/resume/cancel/end any running workout
Interested in learning more? Shoot me an email at email@example.com.