// // HealthKitHelper.swift // Werkout_ios // // Created by Trey Tartt on 8/13/23. // import Foundation import HealthKit struct HealthKitWorkoutData { var caloriesBurned: Double? var minHeartRate: Double? var maxHeartRate: Double? var avgHeartRate: Double? } class HealthKitHelper { // this is dirty and i dont care var returnCount = 0 let healthStore = HKHealthStore() var healthKitWorkoutData = HealthKitWorkoutData( caloriesBurned: nil, minHeartRate: nil, maxHeartRate: nil, avgHeartRate: nil) var completion: ((HealthKitWorkoutData) -> Void)? func getDetails(forHealthKitUUID uuid: UUID, completion: @escaping ((HealthKitWorkoutData) -> Void)) { self.completion = completion self.returnCount = 0 print("get details \(uuid.uuidString)") let predicate = HKQuery.predicateForObject(with: uuid) let query = HKSampleQuery(sampleType: HKWorkoutType.workoutType(), predicate: predicate, limit: 0, sortDescriptors: nil) { (sampleQuery, results, error ) -> Void in if let queryError = error { self.shitReturned() self.shitReturned() print( "There was an error while reading the samples: \(queryError.localizedDescription)") } else { for samples: HKSample in results! { let workout: HKWorkout = (samples as! HKWorkout) self.getTotalBurned(forWorkout: workout) self.getHeartRateStuff(forWorkout: workout) print("got workout") } } } healthStore.execute(query) } func getHeartRateStuff(forWorkout workout: HKWorkout) { print("get heart") let heartType = HKQuantityType.quantityType(forIdentifier: .heartRate) let heartPredicate: NSPredicate? = HKQuery.predicateForSamples(withStart: workout.startDate, end: workout.endDate, options: HKQueryOptions.strictEndDate) let heartQuery = HKStatisticsQuery(quantityType: heartType!, quantitySamplePredicate: heartPredicate, options: [.discreteAverage, .discreteMin, .discreteMax], completionHandler: {(query: HKStatisticsQuery, result: HKStatistics?, error: Error?) -> Void in if let result = result, let minValue = result.minimumQuantity(), let maxValue = result.maximumQuantity(), let avgValue = result.averageQuantity() { let _minHeartRate = minValue.doubleValue( for: HKUnit(from: "count/min") ) let _maxHeartRate = maxValue.doubleValue( for: HKUnit(from: "count/min") ) let _avgHeartRate = avgValue.doubleValue( for: HKUnit(from: "count/min") ) self.healthKitWorkoutData.avgHeartRate = _avgHeartRate self.healthKitWorkoutData.minHeartRate = _minHeartRate self.healthKitWorkoutData.maxHeartRate = _maxHeartRate print("got heart") } self.shitReturned() }) healthStore.execute(heartQuery) } func getTotalBurned(forWorkout workout: HKWorkout) { print("get total burned") let calType = HKQuantityType.quantityType(forIdentifier: .activeEnergyBurned) let calPredicate: NSPredicate? = HKQuery.predicateForSamples(withStart: workout.startDate, end: workout.endDate, options: HKQueryOptions.strictEndDate) let calQuery = HKStatisticsQuery(quantityType: calType!, quantitySamplePredicate: calPredicate, options: [.cumulativeSum], completionHandler: {(query: HKStatisticsQuery, result: HKStatistics?, error: Error?) -> Void in if let result = result { self.healthKitWorkoutData.caloriesBurned = result.sumQuantity()?.doubleValue(for: HKUnit.kilocalorie()) ?? -1 print("got total burned") } self.shitReturned() }) healthStore.execute(calQuery) } func shitReturned() { DispatchQueue.main.async { self.returnCount += 1 print("\(self.returnCount)") if self.returnCount == 2 { self.completion?(self.healthKitWorkoutData) } } } }