I really want the results from executing a HKSampleQuery. But, I always cannot get the results right after executing the query.
My case is below (error processing code is deleted):
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)
// get the latest step count sample
let stepSampleQuery: HKSampleQuery = HKSampleQuery(sampleType: (stepCountQty)!,
predicate: nil,
limit: 1,
sortDescriptors: [sortDescriptor]) {
(query, results, error) -> Void in
if let result = results as? [HKQuantitySample] {
// result[0] is the sample what I want
self.lastStepDate = result[0].startDate
print("readLastStep: ", self.lastStepDate)
}
}
self.healthStore.executeQuery(query)
// now, I want to use the "self.lastStepDate"
// But, I cannot get the appropriate value of the variable.
I don't think the code run progressively. When does resultHandler of HKSampleQuery run? I really want the handler code to run before I use the results from the query.
When resultsHandler runs is documented in the HKSampleQuery reference:
After instantiating the query, call the HKHealthStore class’s executeQuery: method to run this query. Queries run on an anonymous background queue. As soon as the query is complete, the results handler is executed on the background queue. You typically dispatch these results to the main queue to update the user interface.
Since the query is performed asynchronously, you should perform work that depends on the results of the query in response to resultsHandler being called. For instance you could do the following:
// get the latest step count sample
let stepSampleQuery: HKSampleQuery = HKSampleQuery(sampleType: (stepCountQty)!,
predicate: nil,
limit: 1,
sortDescriptors: [sortDescriptor]) {
(query, results, error) -> Void in
if let result = results as? [HKQuantitySample] {
// result[0] is the sample what I want
dispatch_async(dispatch_get_main_queue()) {
self.lastStepDate = result[0].startDate
print("readLastStep: ", self.lastStepDate)
self.doSomethingWithLastStepDate()
}
}
}
self.healthStore.executeQuery(query)
Note that since the handler gets called on a background queue, I've done the work related to lastStepDate on the main queue to avoid synchronization issues.