1 year ago
#357336
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:
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