Streaming is available in most browsers,
and in the Developer app.
-
Build a multi-device workout app
Learn how you can get iPhone involved in your Apple Watch-based workout apps with HealthKit. We'll show you how to mirror workouts between devices and take a ride with cycling data types. Plus, get to know HealthKit for iPad.
Resources
Related Videos
WWDC23
WWDC21
WWDC20
-
Download
♪ Mellow instrumental hip-hop ♪ ♪ Hello and welcome.
My name is Sirisha, and I'm an engineer on the HealthKit team.
Today, there are hundreds of health and fitness apps in the App Store that help users get healthy and stay healthy.
And for them all, HealthKit provides a centralized encrypted database, so your amazing apps can show your users a cohesive view of their health data.
Now, the Workout APIs are some of the most powerful that HealthKit provides, and I love them.
For today's video, I've created a sample cycling app for Apple Watch to track my cycling workouts.
And for easier access, I would love to mount my iPhone on the handlebars to use as a cycling computer.
That way, I can get a quick and easy view of the live metrics displayed on my Apple Watch without having to take my hands off the handlebars.
HealthKit is introducing new Workout APIs to control and mirror active workout sessions between Apple Watch and iPhone.
Updating support for cycling workouts with the addition of new data types for tracking cycling speed, power, cadence, and functional threshold power, or FTP.
And if that wasn't enough, HealthKit along with the Health app is now on iPad.
Now, your customers signed into their iCloud account on iPad will see their health data synced through HealthKit to their iPad.
Just imagine the richer health and post-workout experience you can provide.
Today, I'll use my sample app to demonstrate how to mirror a workout running on Apple Watch with a paired iPhone.
Then, I'll add some code to show you how to collect new cycling metrics and sync them across devices.
And I'll wrap up with the authorization details required to display workouts on iPad.
So let's check out how Apple Watch, iPhone, and iPad can work together to provide a great workout experience.
In my example, I'm running the workout on Apple Watch.
I'm using a workout session as a centralized object to manage its life cycle, starting, pausing, and stopping.
If you're not already familiar with workout sessions, you might want to watch previous talks, "New ways 'to work with Workouts," and "Build a workout app for Apple Watch." Now, for me to control the workout from my iPhone, I need to get this workout session from my Apple Watch to my iPhone.
And to do so, I'll use HealthKit's new mirrored session APIs.
When a mirrored session starts on my Apple Watch, if my iPhone app is not running, it will be launched in the background and handed over the workout session.
To receive the session, my iPhone app needs to be ready.
So, first I'll set up a handler in the iPhone app launch sequence using the HealthStore.
That way, it will be ready to receive the session from my Apple Watch.
Every time my iPhone app is launched in the foreground or the background, I'll implement the mirroring start handler in order to receive the active workout session passed from my Apple Watch.
Next, I'll create a workout configuration with an activity type of cycling.
Then I'll call the existing Start Watch App API in my iPhone app to launch the app on my paired Apple Watch and pass the workout configuration.
When I receive the configuration from my iPhone, I can create a workout session in my Apple Watch app.
The workout session on my Apple Watch is called the primary session.
And the workout session on my iPhone is called the mirrored session.
So here's how it looks.
When I start a workout in my iPhone app, my app on my Apple Watch gets launched with the configuration sent from my iPhone.
So far, so good.
Now the thing that makes this API so convenient is that HealthKit takes care of keeping both the primary and the mirrored session states in sync.
For example, when the primary session is paused on my Apple Watch, the mirrored session on my iPhone is paused as well.
In addition to getting a copy of the active workout session to my iPhone, HealthKit also provides a new API to exchange relevant workout data between both devices, and provides the ability to begin and end activities as well as generate events.
OK, now that I have my primary session ready and my iPhone ready to receive the handler, I'll start mirroring from my Apple Watch by calling startMirroringToCompanionDevice and start the primary session.
Once I call startMirroring on Apple Watch, HealthKit launches my companion iPhone app in the background, gives my app 10 seconds to start a live activity and call a handler to start mirroring.
Great, so we have started the session on the Apple Watch and got the copy on iPhone.
Now, let me show you how the session state is communicated between the devices.
In my example app, I want to show my users the state of the workout session, like whether the session is running, paused, et cetera.
So I'll set up the session delegate on Apple Watch and iPhone to monitor the session state updates and the events generated.
Keep in mind that it is important to keep a reference to the retrieved mirrored session on the iPhone app.
Calling startActivity on my Apple Watch starts the primary session and changes the session state to running.
This state update is delivered to my Apple Watch app since it's set as session delegate of the primary session.
My app on my iPhone also gets the state update through the mirrored session delegate.
It's that easy to bring an active workout session to iPhone and monitor the changes on a session.
So here's what it looks like.
When a workout session is started on my Apple Watch, the pause button on my iPhone and my Apple Watch is activated to indicate that the workout session is running.
In addition to syncing session states between the primary and the mirrored session, I can also generate and send events like pause and resume.
When I pause the workout session on my Apple Watch, both my Apple Watch app and the mirrored session on my iPhone get notified about the pause event through their session delegate.
And that looks like this.
When I pause a workout session on my Apple Watch, the resume button on both my devices becomes active.
Now that I have a workout session on my iPhone, I can control the workout from iPhone as well.
When I resume the mirrored session on my iPhone, the primary session delegate on my Apple Watch gets notified about the state change and the mirrored session delegate gets a resume event.
Next, I would like to show you how to take advantage of the new cycling features HealthKit is introducing this year, including new data types such as cycling speed, power, cadence; a new ability to directly connect to Bluetooth devices designed to provide these data types, similar to how a heart rate monitor collects and writes heart rate data to the health database; and finally, the ability for HealthKit on Apple Watch to automatically calculate and save FTP based on the data collected from these Bluetooth devices.
My bike has a power meter that collects power and cadence, which I paired with my Apple Watch.
The sensor writes the data to my Apple Watch, and I would like to extend my app to send that data to my iPhone for display as I ride.
To do this, I'll first start collecting cycling metrics using the recommended workout builder API beginCollection.
And then I'll send the data using the sendData(toRemoteWorkoutSession) API.
To send the cycling metrics, I'll package the speed, cadence, and power data received from Bluetooth sensors on my Apple Watch and call sendData(toRemoteWorkoutSession) on the primary session.
As a result, the mirrored session delegate on my iPhone will receive the didReceiveDataFromRemoteDevice call with the package data, which I can unpack and display on my iPhone.
Here is how it looks like with my example app sending cycling metrics from my Apple Watch and how they are displayed in my iPhone app.
Using sendData(toRemoteWorkoutSession) I can also send data in the opposite direction from my iPhone to my Apple Watch.
In my example, I want to keep track of my water intake during a workout so I can analyze it afterwards in the hopes of creating a better hydration plan for my next ride.
To do this, I'll package and send the amount of water I consume on the mirrored session from my iPhone to Apple Watch.
The primary session's delegate method didReceiveDataFromRemoteDevice is called with the packaged data which I'll unpack and save on my Apple Watch.
So here's how it looks in my example app.
When I tap the button to count each ounce of water I take, it sends it to my Apple Watch, where it displays the total amount of water consumed.
Now I can stop mirroring the session anytime during the workout by calling stopMirroringToCompanionDevice API.
Calling this method will stop sending data to the companion device and the mirrored session's didDisconnectFromRemoteDevice WithError delegate method will be called.
And when I'm done cycling, I'll end the primary session and save it on the Apple Watch by finishing the builder.
After saving the workout sample on Apple Watch, it syncs to my other devices, and I can now show the post-workout summary with more detailed charts and visualizations.
Great! My next step is to present the post-workout summary in my app running on my iPad.
Since the workout I just saved on Apple Watch automatically syncs to iPad, I only need to make a few changes to visualize my workout data.
Like any app accessing HealthKit data, my app on iPad will will first need to get user authorization.
When an app requests authorization, the authorization sheet is shown if needed.
On iPad, your app might have multiple window scenes, so it's important to ensure that the authorization sheet is shown over the appropriate scene.
To do this in my app, I'll first import HealthKitUI framework.
I'll specify the data types I'm interested in reading, specifically active energy, cycling speed, power, cadence, heart rate, and workout samples.
Then, since I built a SwiftUI app, I'll use the new healthDataAccessRequest view modifier from the HealthKitUI framework and pass the data types I want to share and read, as well as a trigger.
Setting the trigger to true will present the authorization sheet in my app.
For a UIKit app, you would set the healthStores.authorizationView ControllerPresenter property, and then request authorization with the types to share and read.
Now, with the authorization taken care of, let's check out my workout on iPad.
Amazing! Now I can access my workout data and take advantage of the iPad's screen size to create a richer experience for my app.
Isn't it super easy? Now you can start and control a workout from your iPhone, collect and sync rich cycling data from your Apple Watch, and finally, view the workout details on your iPad.
To wrap up, be sure to update your app to support authorization on iPad.
If your Fitness app involves cycling, you can add support for new data types.
If you build workout apps on iPhone and Apple Watch, check out the new mirrored session APIs to start mirroring data and controlling state between both devices.
If your app needs it, use sync identifiers and version numbers to keep the data consistent across your server and users' devices.
And finally, give us your feedback.
We want to support the features you need to keep building those amazing apps to keep the world healthy.
Thank you for watching.
♪
-
-
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.