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.