Track a workout on Apple Watch.
Use workout sessions to track a user’s activity on Apple Watch. While the session runs, the system fine-tunes the watch’s sensors for the specified activity. For example, all workout sessions generate high-frequency heart rate samples; however, an outdoor cycling activity generates accurate location data, while an indoor cycling activity doesn’t.
To track workouts on Apple Watch, you must set up, start, and save a workout session. Make starting and stopping workouts on Apple Watch as easy and obvious as possible. The app must clearly indicate when a workout session is in progress, and either automatically save workout data for the user, or provide a clear option to explicitly save or discard workout data. Finally, the watchOS app should provide clear feedback when a workout is successfully saved. For more information, see Health and Fitness in watchOS Human Interface Guidelines.
Set Up the App
Before creating a workout session, you must set up HealthKit and request permission to read and share any health data your app intends to use. For step-by-step instructions, see Setting Up HealthKit.
For workout sessions, you must request permission to share workout types. You may also want to read any data types automatically recorded by Apple Watch as part of the session.
Apps with an active workout session can run in the background, so you need to add the background modes capability to your WatchKit App Extension.
Workout sessions require the Workout processing background mode. If your app plays audio or provides haptic feedback during the workout session, you must also add the Audio background mode (see Figure 1).
Start a Session
To start a workout session, begin by creating a configuration object for the workout.
Use the configuration to set the type of activity and the location for the workout. Apple Watch optimizes both the sensors and the calorimetry based on the configuration.
For example, while the session runs, Apple Watch automatically saves active energy-burned samples to the HealthKit store. HealthKit provides optimized calorie calculations for run, walk, cycle, stair-climbing, elliptical, and rowing activities. Furthermore, the calculations for run, walk, and cycle activities differ between indoor and outdoor locations. For all other activities, the system estimates calories based on the data from Apple Watch’s sensors. This rate is never lower than the brisk walk burn rate.
Next, use the configuration to create your workout session and get a reference to the session’s
HKWorkout class’s initializer can throw an exception if the configuration is invalid, so you need to wrap the initializer in a
Then, create an
HKLive object and assign it to the workout builder.
Use the same configuration object for the workout session and the live data source. While the session runs, Apple Watch automatically collects data about the workout, and saves samples to the HealthKit store. For example, an outdoor running session collects and saves
You can assign delegates to monitor both the workout session and the workout builder.
HKWorkout receives updates whenever the session’s state changes, an event occurs, or the session fails due to an error. Your
HKLive receives updates when either Apple Watch or your app adds a new sample or event to the builder.
By default, the workout session automatically forwards all events to the builder, so both delegates should receive the same set of events. However, you can set the builder’s
should property to
false if you want to control the events set to the builder.
Finally, start the session and the builder.
Your app’s user interface should clearly indicate that a workout session is running. Use data passed to your
HKLive to update information about the session.
Handle Samples and Events
While the session runs, Apple Watch automatically collects and adds samples and events based on the workout configuration. You can record additional information by adding your own events and samples to the workout. To add samples, call the builder’s
add(_: method. To add events, call the
Typically, you should update your app’s user interface whenever the builder receives a new sample or event. To respond to new samples, implement your
HealthKit calls this method whenever the builder receives a new sample. Your implementation should examine the samples and update your app’s user interface—for example, by updating the current distance traveled, calories burned, and pace during a run. Use the workout builder’s
statistics(for:) method to calculate statistics, such as the total, average, minimum, or maximum, for any types that have new data.
HealthKit calls this method whenever the builder receives a new event. Use the builder’s
workout property to examine the last event, and update your user interface as needed. For example, when a
HKWorkout event occurs, you can increment the number of laps shown.
Run in the Background
When your app has an active workout session, it continues to run in the background. Background execution grants your app the following abilities:
Your app continues to run throughout the entire workout session, even when the user lowers their wrist or interacts with a different app. When the user raises their wrist, your app reappears, letting the user quickly check their current progress and performance.
If the user navigates back to the watch face, Apple Watch displays a small icon at the top of the screen, indicating that a workout session is running. Users can tap the icon to navigate back to your app.
Your app continues to receive data from HealthKit and Apple Watch’s sensors in the background. Use this data to keep your app up to date at all times. For example, your app could display the user’s current heart rate, the distance that the user has cycled, and any other relevant statistics whenever the user raises their wrist.
Your app can alert the user using audio or haptic feedback while running in the background.
To maintain high performance on Apple Watch, you must limit the amount of work your app performs in the background. If your app uses an excessive amount of CPU while in the background, watchOS may suspend it. Use Xcode’s CPU report tool or the time profiler in Instruments to test your app’s CPU usage. The system also generates a log with a backtrace whenever it terminates your app.
Coordinate with the Companion App
If the watchOS app has an iOS companion, be sure to keep both apps in sync. This is particularly important if the user can start workouts on either device.
If the user starts the workout in your watchOS app, and then tries to end it in the iOS companion, the iOS app should instruct the user to end the workout in your watchOS app. Otherwise, Apple Watch workout continues to run, which can lead to accidentally saving invalid data to the HealthKit store.
If the user starts a workout in the iOS companion, and then opens your watchOS app, the watchOS app should automatically start a workout session for the workout in progress. If you save the workout in the watchOS app, you can incorporate data from the iOS workout. For example, you should set the workout’s
startto the iOS workout’s start. Also, if your app calculates its own calories, you can retroactively give credit for the calories burned before the workout session began.
If the user doesn’t start and stop a workout session in your watchOS app, don’t try to retroactively create a workout session on Apple Watch.
End a Session
end method sets the workout’s end date and deactivates the builder. The
finish method saves the workout and its associated data to the HealthKit store.
Recover from Crashes
If your app crashes during a workout session, the system calls your extension delegate’s
handle method when the app relaunches. In your implementation of this method, call the HealthKit store’s
recover method. HealthKit attempts to restore the previous workout session, returning either a new session object or an error to the completion block.
As soon as you receive the session object, you must access its builder and set up your data source and delegates again.