WWDC 2018 and HealthKit – Workouts – Introducing HKLiveWorkoutBuilder

We have setup the iPhone to request authorization and the Apple Watch. Let’s begin a workout and track the user’s heart rate and how the APIs have changed in watchOS 5 after WWDC 2018.

Specifically we’ll look at the power of HKLiveWorkoutBuilder, which simplifies the way we track health data during workouts.

Starting a Workout

To start a workout, you’ll need the HKHealthStore, which was instantiated in the first step, as well as the HKWorkoutActivityType which defines the type of workout you are doing. With those you call healthStore.start(session) to start the workout:

When the workout is completed you simply call healthStore.end(session) to end the workout session.

To listen to workout state changes, implement the delegate HKWorkoutSessionDelegate and the method workoutSession(HKWorkoutSession, didChangeTo: HKWorkoutSessionState, fromState: HKWorkoutSessionState, date: Date):

Tracking Health Data

To track health data, you are going to want to use one of the plethora of HKQuery types but most likely a combination of HKObserverQuery and HKSampleQuery. The HKObserverQuery will indicate when a change has been made. HKSampleQuery will query the actual values.

When the workout is started, we begin the set of HKObserverQueries. In our callback, observerQuery(HKObserverQuery, hasCompleted: HKObserverQueryCompletionHandler, withError: Error?), if the objectType is a HKSampleType then we create a HKSampleQuery for the latest sample from that data.

On the HKSampleQuery callback, sampleQuery(HKSampleQuery, withSamples: [HKSample]?, andError: Error?), we get the quantity from the sample and update the UI on the main thread with that data .

Health Data and Workouts after WWDC 2018

While the process, isn’t the most complicated, watchOS 5 and iOS 12 has simplified the process considerably with HKLiveWorkoutBuilder. HKWorkoutBuilder and it’s watchOS specific version HKLiveWorkoutBuilder make it easy to build workouts, start them, and track data during a workout.

From WWDC 2018, we see a few changes made in the API with how to create and start a  HKWorkoutSession. However the main change is in how the we are creating a HKLiveWorkoutBuilder.

As you can see we are passing a delegate to the HKLiveWorkoutBuilder. This is so we can collect health data as the workout progresses.

In the method workoutBuilder(HKLiveWorkoutBuilder, didCollectDataOf: Set), you can update the UI based on the data collected. For HKQuantityType, you can access the data by calling HKWorkoutBuilder.statistics(for: HKQuantityType). An HKStatistics object contains a variety of statistical info and in watchOS 5 added the method HKStatistics.mostRecentQuantity() which returns the most recent value. If you only need the most recent data, you can update your UI with that data on the main thread.

Conclusion

The ability to create, manage, and track workouts in watchOS is reasonable. However, watchOS 5 has made it even easier.

  • In watchOS 4, you need the health store to start the workout session.
    In watchOS 5, you need the health store only at instantiation not at start.
  • HKWorkoutSessionDelegate allows you track the state of the workout session and update the UI accordingly.
  • In watchOS 4, you need to track the health data using a combination of HKObserverQuery and other HKQuery subclasses such as HKSampleQuery to query HKSample data.
  • In watchOS 5, HKLiveWorkoutBuilder allows you to collect the workout data without needing to use queries.

If you are interested in learning more, watch the presentation, New Ways to Work with Workouts from WWDC 2018. For more info on how to develop with HealthKit, take a look at our recent posts here and for WWDC 2018 sign up for updates here.