class HealthKitQueryBuilder
import Foundation
import HealthKit
class HealthKitQueryBuilder:ObservableObject {
let healthStore: HKHealthStore
let dateFormatter = DateFormatter()
@Published var hourlyStpCount: [HealthData]?
init(healthStore: HKHealthStore) {
self.healthStore = healthStore
}
func readHourlyStepCount(){
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
var hourlyStepCount = [HealthData]()
guard let stepCountType = HKObjectType.quantityType(forIdentifier: .stepCount) else {
fatalError("*** Unable to get the step count type ***")
}
var interval = DateComponents()
interval.hour = 1
let calendar = Calendar.current
let anchorDate = calendar.date(bySettingHour: 0, minute: 55, second: 0, of: Date())
let query = HKStatisticsCollectionQuery.init(quantityType: stepCountType,
quantitySamplePredicate: nil,
options: .cumulativeSum,
anchorDate: anchorDate!,
intervalComponents: interval)
query.initialResultsHandler = { query, results, error in
let startDate = calendar.date(byAdding: .hour,value: -24, to: Date())
DispatchQueue.main.async {
results?.enumerateStatistics(from: startDate!,to: Date(), with: { (result, stop) in
hourlyStepCount.append(HealthData(unit: "count", startDate: self.dateFormatter.string(from: result.startDate) , endDate: self.dateFormatter.string(from: result.endDate), value: (result.sumQuantity()?.doubleValue(for: HKUnit.count()) ?? 0)))
})
print("Hourly step count : \(hourlyStepCount)")
self.hourlyStpCount = hourlyStepCount
}
}
healthStore.execute(query)
}
}
class DataPointsJSONBuilder
import Foundation
import HealthKit
import SwiftUI
class DataPointsJSONBuilder {
let healthStore: HKHealthStore
@ObservedObject var queryBuilder: HealthKitQueryBuilder
init(healthStore: HKHealthStore) {
self.healthStore = healthStore
self.queryBuilder = HealthKitQueryBuilder(healthStore: healthStore)
}
func createJSON() ->String?{
queryBuilder.readHourlyStepCount()
let totalStepCount = queryBuilder.hourlyStpCount
let averageRestingHeartRate = [HealthData(unit: "count", startDate: "2022-11-22 10:55:00 PM +0000", endDate: "2022-11-22 11:55:00 PM +0000", value: 100.0)]
let averageHeartRateVariability = [HealthData(unit: "count", startDate: "2022-11-22 10:55:00 PM +0000", endDate: "2022-11-22 11:55:00 PM +0000", value: 100.0)]
let averageRespiratoryRate = [HealthData(unit: "count", startDate: "2022-11-22 10:55:00 PM +0000", endDate: "2022-11-22 11:55:00 PM +0000", value: 100.0)]
let totalSleepDuration = [HealthData(unit: "count", startDate: "2022-11-22 10:55:00 PM +0000", endDate: "2022-11-22 11:55:00 PM +0000", value: 100.0)]
let heartRate = [HealthData(unit: "count", startDate: "2022-11-22 10:55:00 PM +0000", endDate: "2022-11-22 11:55:00 PM +0000", value: 100.0)]
let systolicBloodPressure = [HealthData(unit: "count", startDate: "2022-11-22 10:55:00 PM +0000", endDate: "2022-11-22 11:55:00 PM +0000", value: 100.0)]
let diastolicBloodPressure = [HealthData(unit: "count", startDate: "2022-11-22 10:55:00 PM +0000", endDate: "2022-11-22 11:55:00 PM +0000", value: 100.0)]
let oxygenSaturation = [HealthData(unit: "count", startDate: "2022-11-22 10:55:00 PM +0000", endDate: "2022-11-22 11:55:00 PM +0000", value: 100.0)]
let currentGlucose = [HealthData(unit: "count", startDate: "2022-11-22 10:55:00 PM +0000", endDate: "2022-11-22 11:55:00 PM +0000", value: 100.0)]
let averageGlucose = [HealthData(unit: "count", startDate: "2022-11-22 10:55:00 PM +0000", endDate: "2022-11-22 11:55:00 PM +0000", value: 100.0)]
let dataPoints = DataPointsObj(totalStepCount: totalStepCount, averageRestingHeartRate: [], averaHeartRatevariability: [], averageRespiratoryRate: [], totalSleepDuration: [], heartRate: [], systolicBloodPressure: [], diastolicBloodPressure: [], oxygenSaturation: [], currentGlucoseValue: [], averageGlucoseValue: [])
guard let JSON = encodeToJSON(dataPointsObj: dataPoints) else {
return nil
}
return JSON
}
private func encodeToJSON(dataPointsObj: DataPointsObj) -> String? {
let encoder = JSONEncoder()
encoder.outputFormatting = .withoutEscapingSlashes
do {
let result = try encoder.encode(dataPointsObj)
if let jsonString = String(data: result, encoding: .utf8){
return jsonString
}
return nil
} catch {
return nil
}
}
}
I have above 2 classes implemented to read data from apple health kit and make a json object to send it to backend. But after the data is fetched data is not published to DataPointsJSONBuilder
class. I get data printed inside HealthKitQueryBuilder
class successfully and I have added the code for step count only for now. I call the createJSON
function inside onAppear
in the UI as follows.
.onAppear(){
print(DataPointsJSONBuilder(healthStore: healthStore).createJSON()!)
}
What I want to do is read data from healthkit and bring them to DataPointsJSONBuilder
class to send it to backend through a REST api. I don't understand why I hourlyStpCount is not updated when data is read. If there is a wrong implementation here, kindly correct me or suggest a method to solve my problem. Thanks!