I've written a function that retrieves max heart rate and average heart rate from HKHealthStore
. Though both HKStatisticQuery()
calls work, due to the fact that completion handlers are asynchronous, the return values (maxHRT, avgHRT) for the function are (0, 0).
What is an elegant way to wait for both completion handlers to return, before updating return values and exiting function?
Code:
func calcHeartRateStatistics() -> (Double, Double){
var maxHRT:Double = 0
var avgHRT:Double = 0
// First specify type of sample we need, i.e. Heart Rate Type
//
let sampleType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)
// Create query predicate so result only returns objects within the period between Start Date
// and End Date
//
let predicate = HKQuery.predicateForSamplesWithStartDate(pvtStartDate, endDate: pvtEndDate, options: .None)
// Query for Maximum Heart Rate that occurred between Start Date and End Date
//
let queryMaxHeartRate = HKStatisticsQuery(quantityType: sampleType!,
quantitySamplePredicate: predicate,
options: .DiscreteMax)
{ [unowned self] (query, result, error) in
if let maxQuantity = result?.maximumQuantity() {
let maxHeartRate = maxQuantity.doubleValueForUnit(HKUnit(fromString: "count/min"))
maxHRT = round(maxHeartRate)
}
}
// Query for Average Heart Rate that occurred between Start Date and End Date
//
let queryAverageHeartRate = HKStatisticsQuery(quantityType: sampleType!,
quantitySamplePredicate: predicate,
options: .DiscreteAverage)
{ [unowned self] (query, result, error) in
if let averageQuantity = result?.averageQuantity(){
let avgHeartRate = averageQuantity.doubleValueForUnit(HKUnit(fromString: "count/min"))
avgHRT = round(avgHeartRate)
}
}
pvtHealthStore.executeQuery(queryMaxHeartRate)
pvtHealthStore.executeQuery(queryAverageHeartRate)
return (maxHRT, avgHRT)
} // calcHeartRateStatistics