- iOS 13.0+
- Xcode 11.2+
- watchOS 6.0+
This sample demonstrates how to create an Apple Watch workout app using the Workout Builder API. The sample displays real-time data, such as heart rate, distance traveled, and elapsed time during an active workout. The user can tap on a button on the inital interface to start the workout, and force-press on the workout interface to bring up the context menu to pause or to stop the workout.
Configure the Sample Code Project
To build and run this sample on your devices, you must first change the bundle IDs to the pattern described in order to provision the apps correctly in your environment:
OS app bundle ID>
WatchKit app target:
OS app bundle ID>.watchkitapp
WatchKit Extension target:
OS app bundle ID>.watchkitapp .watchkitextension
Follow these steps to change the bundle IDs:
Open the sample with the latest version of Xcode.
Select the top-level project.
For the three targets, change the bundle identifier to the appropriate value.
For the targets, select the correct team in the Signing section (next to Team) to let Xcode automatically manage your provisioning profile.
Additionally, configure the
Info files with the correct bundle IDs:
Infofile of the WatchKit app target, and change the value of
App Bundle Identifier
OS app bundle ID>
Infofile of the WatchKit Extension target, and change the value of the
NSExtension > NSExtensionkey to
Attributes > WKApp Bundle Identifier
OS app bundle ID>.watchkitapp
Make a clean build and run the apps on your devices. Restart the devices in case Xcode is unable to install and run the apps.
Workout apps access the HealthKit data store for real-time data, and to save workouts. The app must request authorization from the user to access the data and save the workout.
You must make this request in both the WatchKit extension and in the companion iOS app, because watchOS will ask the user to give authorization on the companion iPhone.
Create the Workout Session and Live Workout Builder
First, the app creates an
HKWorkout object, and sets its properties to describe the type of activity corresponding to this workout. In this case, the app sets the
activity property to
.running to represent a running workout activity. HealthKit provides constants for dozens of popular workout and fitness activities.
Then the app creates the
HKWorkout, which is required in order to save a workout in the HealthKit store. This initialization can throw an exception if the workout configuration parameter is invalid. Then the app asks the workout session object for the associated
HKLive object. The
HKLive object automates the collection of HealthKit quantity types that the app displays to the user during the workout.
Set the Data Source
The app initializes a new
HKLive object, configured with the same workout configuration object used earlier in creating the workout session. As a result, the data source infers the quantity types to collect. The app sets the
HKLive object as the workout builder object’s data source.
Start the Session and the Builder
The workout session and workout builder objects are now fully set up, so the app starts the workout session and the workout builder’s data collection.
Update the Workout Timer
To let the user know how long the workout has been in progress, the app implements the workout timer as a
WKInterface object. The timer updates every time the workout builder collects an
HKWorkout event. To do this, the app implements the
workout method, which updates the timer using the value of the elapsed time from the workout builder.
Next, if the workout session is running, the app starts the timer. If the session is not running, the app stops the timer.
Update the User Interface
When HealthKit has new quantities available, it calls the
workout method. The app iterates on the collected quantity types to retrieve the most recent values and to update the user interface. For example, the app uses the following process to update the label for the heart rate. First, the app calls the workout builder’s’
statistics(for:) method to obtain the
HKStatistics object corresponding to the quantity type in the current iteration.
Then, the app retrieves the most recent value collected from the
HKStatistics object, rounds it, and sets the label’s text.
Save the Workout
When the user has finished working out, they tap on the Stop button in the context menu. In response, the app should stop collecting data and end the workout session. The app calls the workout builder’s
end method to end the collection of data. Then the app saves the workout along with the associated collected samples and events by calling
finish. In the completion block, the app dismisses the workout interface, and presents the initial interface again.