HealthKit Tutorial With Swift: Workouts

This HealthKit tutorial shows you step by step how to track workouts using the HealthKit APIs by integrating an app with the system’s Health app. By Felipe Laso-Marsetti.

4.1 (7) · 2 Reviews

Download materials
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Adding Samples While Saving a Workout

Open WorkoutDataStore.swift and paste this new method right after save(prancerciseWorkout:completion:):

private class func samples(for workout: PrancerciseWorkout) -> [HKSample] {
  //1. Verify that the energy quantity type is still available to HealthKit.
  guard let energyQuantityType = HKSampleType.quantityType(
    forIdentifier: .activeEnergyBurned) else {
        fatalError("*** Energy Burned Type Not Available ***")
  }
  
  //2. Create a sample for each PrancerciseWorkoutInterval
  let samples: [HKSample] = workout.intervals.map { interval in
    let calorieQuantity = HKQuantity(unit: .kilocalorie(),
                                     doubleValue: interval.totalEnergyBurned)
    
    return HKCumulativeQuantitySeriesSample(type: energyQuantityType,
                                                  quantity: calorieQuantity,
                                                  start: interval.start,
                                                  end: interval.end)
  }
  
  return samples
}

Hey, you’ve seen this before! It’s the same thing you did when submitting a body mass index sample in the previous HealthKit tutorial. You’re doing it inside of map, creating a sample for each PrancerciseWorkoutInterval associated with your PrancerciseWorkout.

Now, you’ll make a few adjustments to the code to attach the samples to your workout.

Inside the save(prancerciseWorkout:completion:) method, replace the following code:

guard let quantityType = HKQuantityType.quantityType(forIdentifier:
  .activeEnergyBurned) else {
    completion(false, nil)
    return
}

let unit = HKUnit.kilocalorie()
let totalEnergyBurned = prancerciseWorkout.totalEnergyBurned
let quantity = HKQuantity(unit: unit,
                          doubleValue: totalEnergyBurned)
let sample = HKCumulativeQuantitySeriesSample(type: quantityType,
                                              quantity: quantity,
                                              start: prancerciseWorkout.start,
                                              end: prancerciseWorkout.end)

//1. Add the sample to the workout builder
builder.add([sample]) { (success, error) in
  guard success else {
    completion(false, error)
    return
  }
  
  //2. Finish collection workout data and set the workout end date
  builder.endCollection(withEnd: prancerciseWorkout.end) { (success, error) in
    guard success else {
      completion(false, error)
      return
    }
    
    //3. Create the workout with the samples added
    builder.finishWorkout { (_, error) in
      let success = error == nil
      completion(success, error)
    }
  }
}

With this:

let samples = self.samples(for: prancerciseWorkout)
    
builder.add(samples) { (success, error) in
  guard success else {
    completion(false, error)
    return
  }
      
  builder.endCollection(withEnd: prancerciseWorkout.end) { (success, error) in
    guard success else {
      completion(false, error)
      return
    }
        
    builder.finishWorkout { (workout, error) in
      let success = error == nil
      completion(success, error)
    }
  }
}

This code prepares a list of samples using your Prancercise workout. Then, it adds them to the workout builder as you’ve done before.

Build and run the app. Tap on Prancercise Workouts. Then, tap the + button to track a new Prancercise workout. Record a few Prancercise sessions and tap Done to save them to HealthKit as a single Prancercise workout.

Viewing Workout Samples in the Health App

You aren’t going to see anything new in the Prancercise Tracker’s user interface, but there’s loads of data in your Health app to peruse.

Open the Health app. Tap the second tab labeled Health Data, then tap on Activity. You should see a breakdown of your workouts for the day.

HealthKit tutorial

You can see very short Prancercise sessions recorded, so Activity says the user has spent one minute exercising. That’s fine. You have already established the relative intensity of the Prancercise regimen, so it ought to be enough physical exertion for a day. :]

Tap Workouts. The next screen will give you a breakdown of your workouts for the day. In your case, you want to see where all those data points came from.

Tap Show All Data. This will take you to a screen that displays all your workouts for the day, along with their source app.

HealthKit tutorial

Neat. The RW Logo shows that the workouts came from Prancercise Tracker.

Tap on a workout to view its details. Scroll down to the Workout Samples section, and then tap on the cell displaying the total active energy.

HealthKit tutorial

At this point, you should see a list of active energy samples associated with the Prancercise workout you just tracked.

HealthKit tutorial

Tap on a sample, and you can see when your short Prancercise session started and finished.

HealthKit tutorial

Awesome! You’ve built an app that not only tracks a workout but also tracks interval training within that workout.

Where to Go From Here?

You can download the final project using the Download materials button at the top or bottom of this tutorial.

This HealthKit tutorial has given you some insight into the basic concepts of HealthKit and how to use them in your own apps. To know more about HealthKit, these are the most relevant resources:

After going through those documents and videos, you’ll be ready to dig into some more advanced aspects of HealthKit and add improvements to this app. For instance, you could add new types of samples or workouts, calculate Statistics using HKStatisticsQuery or observe changes in the store information with HKObserverQuery.

I hope you enjoyed this HealthKit tutorial and, as always, if you have any questions or comments please join the forum discussion below!