I am creating an IOS application meant to fetch certain health points, accumulative and average, over a certain period of time. The time is received via a timer start and a timer end, and once the timer is topped the accumulated data points gets saved to a view. While the timer is actively running, I would like the most recent health points to showcase on the UI. I am trying to use these time points in a predicate to use in the query but nothing is being returned when I test the application and I am left with only 0’s. Could it be an issue with how my query is set up?
<code> func updateHealthData(isFinalFetch: Bool = false) {
guard let startDate = startTime else { return }
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: .strictEndDate)
let dispatchGroup = DispatchGroup()
fetchStepsData(predicate: predicate) { dispatchGroup.leave() }
fetchHeartRateData(predicate: predicate) { dispatchGroup.leave() }
fetchWristTemperatureData(predicate: predicate) { dispatchGroup.leave() }
fetchBloodOxygenData(predicate: predicate) { dispatchGroup.leave() }
fetchRespiratoryRateData(predicate: predicate) { dispatchGroup.leave() }
dispatchGroup.notify(queue: .main) {
// Store final session data if this is the last fetch
activityController.addRecordedSession(
activityTitle: activity.title,
accelerometerData: accelerometerData,
gyroscopeData: gyroscopeData,
gravityData: gravityData,
orientationData: orientationData,
heartRate: heartRateAverage,
stepCount: stepCountTotal,
wristTemperature: wristTemperatureAverage,
bloodOxygenLevel: bloodOxygenAverage,
respiratoryRate: respiratoryRateAverage
<code> func updateHealthData(isFinalFetch: Bool = false) {
let endDate = Date()
guard let startDate = startTime else { return }
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: .strictEndDate)
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
fetchStepsData(predicate: predicate) { dispatchGroup.leave() }
dispatchGroup.enter()
fetchHeartRateData(predicate: predicate) { dispatchGroup.leave() }
dispatchGroup.enter()
fetchWristTemperatureData(predicate: predicate) { dispatchGroup.leave() }
dispatchGroup.enter()
fetchBloodOxygenData(predicate: predicate) { dispatchGroup.leave() }
dispatchGroup.enter()
fetchRespiratoryRateData(predicate: predicate) { dispatchGroup.leave() }
dispatchGroup.notify(queue: .main) {
if isFinalFetch {
// Store final session data if this is the last fetch
activityController.addRecordedSession(
activityTitle: activity.title,
totalTime: elapsedTime,
accelerometerData: accelerometerData,
gyroscopeData: gyroscopeData,
gravityData: gravityData,
orientationData: orientationData,
heartRate: heartRateAverage,
stepCount: stepCountTotal,
wristTemperature: wristTemperatureAverage,
bloodOxygenLevel: bloodOxygenAverage,
respiratoryRate: respiratoryRateAverage
)
}
}
}
</code>
func updateHealthData(isFinalFetch: Bool = false) {
let endDate = Date()
guard let startDate = startTime else { return }
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: .strictEndDate)
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
fetchStepsData(predicate: predicate) { dispatchGroup.leave() }
dispatchGroup.enter()
fetchHeartRateData(predicate: predicate) { dispatchGroup.leave() }
dispatchGroup.enter()
fetchWristTemperatureData(predicate: predicate) { dispatchGroup.leave() }
dispatchGroup.enter()
fetchBloodOxygenData(predicate: predicate) { dispatchGroup.leave() }
dispatchGroup.enter()
fetchRespiratoryRateData(predicate: predicate) { dispatchGroup.leave() }
dispatchGroup.notify(queue: .main) {
if isFinalFetch {
// Store final session data if this is the last fetch
activityController.addRecordedSession(
activityTitle: activity.title,
totalTime: elapsedTime,
accelerometerData: accelerometerData,
gyroscopeData: gyroscopeData,
gravityData: gravityData,
orientationData: orientationData,
heartRate: heartRateAverage,
stepCount: stepCountTotal,
wristTemperature: wristTemperatureAverage,
bloodOxygenLevel: bloodOxygenAverage,
respiratoryRate: respiratoryRateAverage
)
}
}
}
<code> // Fetching Functions
func fetchStepsData(predicate: NSPredicate, completion: @escaping () -> Void) {
let stepType = HKQuantityType.quantityType(forIdentifier: .stepCount)!
let query = HKStatisticsQuery(quantityType: stepType, quantitySamplePredicate: predicate, options: .cumulativeSum) { _, result, _ in
if let sum = result?.sumQuantity() {
DispatchQueue.main.async {
self.stepCountTotal = sum.doubleValue(for: HKUnit.count())
healthKitManager.healthStore.execute(query)
func fetchHeartRateData(predicate: NSPredicate, completion: @escaping () -> Void) {
let heartRateType = HKQuantityType.quantityType(forIdentifier: .heartRate)!
let query = HKStatisticsQuery(quantityType: heartRateType, quantitySamplePredicate: predicate, options: .discreteAverage) { _, result, _ in
if let avg = result?.averageQuantity() {
DispatchQueue.main.async {
self.heartRateAverage = avg.doubleValue(for: HKUnit(from: "count/min"))
healthKitManager.healthStore.execute(query)
func fetchWristTemperatureData(predicate: NSPredicate, completion: @escaping () -> Void) {
let wristTempType = HKQuantityType.quantityType(forIdentifier: .bodyTemperature)!
let query = HKStatisticsQuery(quantityType: wristTempType, quantitySamplePredicate: predicate, options: .discreteAverage) { _, result, _ in
if let avg = result?.averageQuantity() {
DispatchQueue.main.async {
self.wristTemperatureAverage = avg.doubleValue(for: HKUnit.degreeCelsius())
healthKitManager.healthStore.execute(query)
func fetchBloodOxygenData(predicate: NSPredicate, completion: @escaping () -> Void) {
let oxygenType = HKQuantityType.quantityType(forIdentifier: .oxygenSaturation)!
let query = HKStatisticsQuery(quantityType: oxygenType, quantitySamplePredicate: predicate, options: .discreteAverage) { _, result, _ in
if let avg = result?.averageQuantity() {
DispatchQueue.main.async {
self.bloodOxygenAverage = avg.doubleValue(for: HKUnit.percent()) * 100
healthKitManager.healthStore.execute(query)
func fetchRespiratoryRateData(predicate: NSPredicate, completion: @escaping () -> Void) {
let respiratoryRateType = HKQuantityType.quantityType(forIdentifier: .respiratoryRate)!
let query = HKStatisticsQuery(quantityType: respiratoryRateType, quantitySamplePredicate: predicate, options: .discreteAverage) { _, result, _ in
if let avg = result?.averageQuantity() {
DispatchQueue.main.async {
self.respiratoryRateAverage = avg.doubleValue(for: HKUnit.count().unitDivided(by: HKUnit.minute()))
healthKitManager.healthStore.execute(query)
<code> // Fetching Functions
func fetchStepsData(predicate: NSPredicate, completion: @escaping () -> Void) {
let stepType = HKQuantityType.quantityType(forIdentifier: .stepCount)!
let query = HKStatisticsQuery(quantityType: stepType, quantitySamplePredicate: predicate, options: .cumulativeSum) { _, result, _ in
if let sum = result?.sumQuantity() {
DispatchQueue.main.async {
self.stepCountTotal = sum.doubleValue(for: HKUnit.count())
}
}
completion()
}
healthKitManager.healthStore.execute(query)
}
func fetchHeartRateData(predicate: NSPredicate, completion: @escaping () -> Void) {
let heartRateType = HKQuantityType.quantityType(forIdentifier: .heartRate)!
let query = HKStatisticsQuery(quantityType: heartRateType, quantitySamplePredicate: predicate, options: .discreteAverage) { _, result, _ in
if let avg = result?.averageQuantity() {
DispatchQueue.main.async {
self.heartRateAverage = avg.doubleValue(for: HKUnit(from: "count/min"))
}
}
completion()
}
healthKitManager.healthStore.execute(query)
}
func fetchWristTemperatureData(predicate: NSPredicate, completion: @escaping () -> Void) {
let wristTempType = HKQuantityType.quantityType(forIdentifier: .bodyTemperature)!
let query = HKStatisticsQuery(quantityType: wristTempType, quantitySamplePredicate: predicate, options: .discreteAverage) { _, result, _ in
if let avg = result?.averageQuantity() {
DispatchQueue.main.async {
self.wristTemperatureAverage = avg.doubleValue(for: HKUnit.degreeCelsius())
}
}
completion()
}
healthKitManager.healthStore.execute(query)
}
func fetchBloodOxygenData(predicate: NSPredicate, completion: @escaping () -> Void) {
let oxygenType = HKQuantityType.quantityType(forIdentifier: .oxygenSaturation)!
let query = HKStatisticsQuery(quantityType: oxygenType, quantitySamplePredicate: predicate, options: .discreteAverage) { _, result, _ in
if let avg = result?.averageQuantity() {
DispatchQueue.main.async {
self.bloodOxygenAverage = avg.doubleValue(for: HKUnit.percent()) * 100
}
}
completion()
}
healthKitManager.healthStore.execute(query)
}
func fetchRespiratoryRateData(predicate: NSPredicate, completion: @escaping () -> Void) {
let respiratoryRateType = HKQuantityType.quantityType(forIdentifier: .respiratoryRate)!
let query = HKStatisticsQuery(quantityType: respiratoryRateType, quantitySamplePredicate: predicate, options: .discreteAverage) { _, result, _ in
if let avg = result?.averageQuantity() {
DispatchQueue.main.async {
self.respiratoryRateAverage = avg.doubleValue(for: HKUnit.count().unitDivided(by: HKUnit.minute()))
}
}
completion()
}
healthKitManager.healthStore.execute(query)
}
</code>
// Fetching Functions
func fetchStepsData(predicate: NSPredicate, completion: @escaping () -> Void) {
let stepType = HKQuantityType.quantityType(forIdentifier: .stepCount)!
let query = HKStatisticsQuery(quantityType: stepType, quantitySamplePredicate: predicate, options: .cumulativeSum) { _, result, _ in
if let sum = result?.sumQuantity() {
DispatchQueue.main.async {
self.stepCountTotal = sum.doubleValue(for: HKUnit.count())
}
}
completion()
}
healthKitManager.healthStore.execute(query)
}
func fetchHeartRateData(predicate: NSPredicate, completion: @escaping () -> Void) {
let heartRateType = HKQuantityType.quantityType(forIdentifier: .heartRate)!
let query = HKStatisticsQuery(quantityType: heartRateType, quantitySamplePredicate: predicate, options: .discreteAverage) { _, result, _ in
if let avg = result?.averageQuantity() {
DispatchQueue.main.async {
self.heartRateAverage = avg.doubleValue(for: HKUnit(from: "count/min"))
}
}
completion()
}
healthKitManager.healthStore.execute(query)
}
func fetchWristTemperatureData(predicate: NSPredicate, completion: @escaping () -> Void) {
let wristTempType = HKQuantityType.quantityType(forIdentifier: .bodyTemperature)!
let query = HKStatisticsQuery(quantityType: wristTempType, quantitySamplePredicate: predicate, options: .discreteAverage) { _, result, _ in
if let avg = result?.averageQuantity() {
DispatchQueue.main.async {
self.wristTemperatureAverage = avg.doubleValue(for: HKUnit.degreeCelsius())
}
}
completion()
}
healthKitManager.healthStore.execute(query)
}
func fetchBloodOxygenData(predicate: NSPredicate, completion: @escaping () -> Void) {
let oxygenType = HKQuantityType.quantityType(forIdentifier: .oxygenSaturation)!
let query = HKStatisticsQuery(quantityType: oxygenType, quantitySamplePredicate: predicate, options: .discreteAverage) { _, result, _ in
if let avg = result?.averageQuantity() {
DispatchQueue.main.async {
self.bloodOxygenAverage = avg.doubleValue(for: HKUnit.percent()) * 100
}
}
completion()
}
healthKitManager.healthStore.execute(query)
}
func fetchRespiratoryRateData(predicate: NSPredicate, completion: @escaping () -> Void) {
let respiratoryRateType = HKQuantityType.quantityType(forIdentifier: .respiratoryRate)!
let query = HKStatisticsQuery(quantityType: respiratoryRateType, quantitySamplePredicate: predicate, options: .discreteAverage) { _, result, _ in
if let avg = result?.averageQuantity() {
DispatchQueue.main.async {
self.respiratoryRateAverage = avg.doubleValue(for: HKUnit.count().unitDivided(by: HKUnit.minute()))
}
}
completion()
}
healthKitManager.healthStore.execute(query)
}
Variables not being updated in an active timer session
Saved final values with no data being showcased
I’ve tried directly fetching active heart rate and showcasing that to see if it is my health authorization that’s an issue but it is not the case since I am able to run that query.