Adam Goldberg
Adam Goldberg

Reputation: 81

How do I print the values of the HKQuantity type I just recorded and saved to Healthkit store?

I am sharing a workout to the HKStore and I have requested the following types tot read:

let typesToRead: Set = [
    HKQuantityType.quantityType(forIdentifier: .heartRate)!,
    HKQuantityType.quantityType(forIdentifier: .activeEnergyBurned)!,
    HKQuantityType.quantityType(forIdentifier: .distanceWalkingRunning)!
]

In my workout session class (that tracks and records an active workout) I am able to record live data and save it to HealthStore but I don't know how to read that data and display it on screen for the users to view live during there workout. (or at least print the heart rate, activeEnergyBurned etc data in console).

Here is the HKLiveWorkoutBuilderDelegate that seems to be sharing the relevant workout data

// MARK: HKLiveWorkoutBuilderDelegate
func workoutBuilder(_ workoutBuilder: HKLiveWorkoutBuilder, didCollectDataOf collectedTypes: Set<HKSampleType>) {
    for type in collectedTypes {
        guard let quantityType = type as? HKQuantityType else {
            return // Nothing to do
        }

        let statistics = workoutBuilder.statistics(for: quantityType)
        let typeDescription = type.description

    }
}

And here is how my workout is activated:

    override func awake(withContext context: Any?) {
        super.awake(withContext: context)

        configuration.activityType = .running
        configuration.locationType = .indoor

        do {
            session = try HKWorkoutSession(healthStore: healthStore, configuration: configuration)
            builder = session.associatedWorkoutBuilder()
        } catch {
            dismiss()
            return
        }

        // Setup session and builder
        session.delegate = self
        builder.delegate = self
        builder.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore, workoutConfiguration: configuration)


        // Start session and builder
        session.startActivity(with: Date())
        builder.beginCollection(withStart: Date()) { (success, error) in
            self.setDurationTimerDate()
        }
    }

Note: I am using Apples new Beta WatchOS 5.0

Upvotes: 4

Views: 1188

Answers (1)

Piidro
Piidro

Reputation: 808

You are doing most of the things, but you need to also enable the collecting of data to the dataSource. In my app I collect distance and heart rate data, I do it like this:

let dataSource = HKLiveWorkoutDataSource(healthStore: healthStore, workoutConfiguration: configuration)

if let hr = HKQuantityType.quantityType(forIdentifier: .heartRate) {
    dataSource.enableCollection(for: hr, predicate: nil)
}
if let distance = HKQuantityType.quantityType(forIdentifier: .distanceWalkingRunning) {
    dataSource.enableCollection(for: distance, predicate: nil)
}

workoutBuilder?.dataSource = dataSource

Then I can print that information in the HKLiveWorkoutBuilderDelegate method like this:

func workoutBuilder(_ workoutBuilder: HKLiveWorkoutBuilder, didCollectDataOf collectedTypes: Set<HKSampleType>) {

    guard let hrType = HKQuantityType.quantityType(forIdentifier: .heartRate),
        let distanceType = HKQuantityType.quantityType(forIdentifier: .distanceWalkingRunning) else {
            return
    }

    if collectedTypes.contains(hrType) {
        if let hrQuantity = workoutBuilder.statistics(for: hrType)?.mostRecentQuantity() {
            // We want to have BPM
            let hrUnit = HKUnit(from: "count/min")
            let hr = Int(hrQuantity.doubleValue(for: hrUnit))

            debugPrint("HR: \(hr)")
        }
    }

    if collectedTypes.contains(distanceType) {
        if let distQuantity = workoutBuilder.statistics(for: distanceType)?.sumQuantity() {
            // We want to have total distance in meters
            let distance = distQuantity.doubleValue(for: HKUnit.meter())

            debugPrint("Distance: \(distance) m")
        }
    }
}

And then I get in console:

"Distance: 6.5 m"
"Distance: 10.4 m"
"HR: 112"
"Distance: 14.3 m"
"HR: 117"
"Distance: 20.8 m"

Upvotes: 8

Related Questions