1 year ago

#357336

test-img

Pasan Induwara

How to get workout heart rate details durations and calculate data like Fat burn/Build fitness

I am building an apple health kit app and now I want to generate how much time users spent on workouts and how much time spent on certain states like extreme, fat burn and some others.

Like this following image:

enter image description here

So far I have got workouts from sample query like this.

  func readWorkouts() async -> [HKWorkout]? {
        
        clearAllWorkoutData()
       
        let predicate = HKQuery.predicateForSamples(withStart: startDate.getDateOnly().toDateOnly(), end: endDate, options: .strictStartDate)
        
        let samples = try! await withCheckedThrowingContinuation { (continuation: CheckedContinuation<[HKSample], Error>) in
            store.execute(HKSampleQuery(sampleType: .workoutType(), predicate: predicate, limit: HKObjectQueryNoLimit,sortDescriptors: [.init(keyPath: \HKSample.startDate, ascending: false)], resultsHandler: { query, samples, error in
                if let hasError = error {
                    continuation.resume(throwing: hasError)
                    return
                }
                
                guard let samples = samples else {
                    fatalError("*** Invalid State: This can only fail if there was an error. ***")
                }
                
                continuation.resume(returning: samples)
            }))
        }
        
        guard let workouts = samples as? [HKWorkout] else {
            return nil
        }
        
        for item in workouts {
  Task{
                await
                self.calculateOtherWorkoutData(startDate: item.startDate, endDate: item.endDate, item: item)
            }
}
     return workouts
    }

Then I called a function to calculate those data.

func calculateOtherWorkoutData(startDate:Date,endDate:Date,item:HKWorkout) async{
        let hrType = HKQuantityType.quantityType(forIdentifier: .heartRate)!
        
        let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: .strictStartDate)
        
        let samples = try! await withCheckedThrowingContinuation { (continuation: CheckedContinuation<[HKSample], Error>) in
            store.execute(HKSampleQuery(sampleType: hrType, predicate: predicate, limit: HKObjectQueryNoLimit,sortDescriptors: [.init(keyPath: \HKSample.startDate, ascending: false)], resultsHandler: { query, samples, error in
                if let hasError = error {
                    continuation.resume(throwing: hasError)
                    return
                }
                
                guard let samples = samples else {
                    fatalError("*** Invalid State: This can only fail if there was an error. ***")
                }
                
                continuation.resume(returning: samples)
            }))
        }
        
        guard let heartrates = samples as? [HKQuantitySample] else {
            return
        }
        
        for heartrate in heartrates {
            
            let beats: Double? = heartrate.quantity.doubleValue(for: HKUnit.count().unitDivided(by: HKUnit.minute()))
            print(heartrate.startDate, heartrate.endDate)
            guard beats != nil else {
                return
            }
            let workoutDiff = item.duration
            if beats! > 0 && beats! < 93{
                self.warmthTime += heartrate.endDate.timeIntervalSince(heartrate.startDate)
            }
            if beats! > 93 && beats! < 111{
                self.fatBurnTime += heartrate.endDate.timeIntervalSince(heartrate.startDate)
            }
            if beats! > 111 && beats! < 130{
                self.buildFitTime += heartrate.endDate.timeIntervalSince(heartrate.startDate)
            }
            if beats! > 130 && beats! < 148{
                self.highIntTime += heartrate.endDate.timeIntervalSince(heartrate.startDate)
            }
            if beats! > 167{
                self.extremeTime += heartrate.endDate.timeIntervalSince(heartrate.startDate)
            }
        }
    }

But I am stuck on getting those durations. if I use total workout durations it calculates again and again. The health kit is measuring heart rates on times but not with durations.

I also tried statistical queries but it only gives those averages and only one heart rate data is coming for one workout like that.

Does anyone have an idea how to accomplish this like in the image I attached?

ios

swift

apple-watch

healthkit

0 Answers

Your Answer

Accepted video resources