How to force a HKQuery to load the most recent steps counts?

healthkit, ios, objective-c

Solution

HealthKit does not always have an up-to-date count of the user's steps and distance travelled. It imports these values, which actually come from CoreMotion.framework, periodically and in response to certain events. If a running application has an open `HKObserverQuery` or `HKStatisticsCollectionQuery` then HealthKit will stream the values to the client but otherwise the samples are just a snapshot from the last import.

So if you'd like to observe changes for a sample type, you should subscribe to updates using an `HKObserverQuery` and then query HealthKit again for the latest values. A more efficient approach would be to use `HKStatisticsCollectionQuery`, though, which has an update handler that will be invoked as the statistics for the samples matching the predicates change.

Finally, if you're only interested up-to-date step counts or distance travelled for at most the past 7 days then I recommend that you consider using CoreMotion.framework directly instead.

Problem

Currently I'm trying to use `HKStatisticsQuery` to get the steps count between a certain time interval. I'm doing test by `shaking` the phone myself. However, it seems that the result I get is not the most recent one, unless: - I open the `Health.app`, keep it running in background, and do the test again in my app; - I open the `UP app`, keep it running in background, and do the test again in my app. And if I force-quit the `Health.app` or`UP app`, my app will not be able to get the most recent data again. So UP must be doing something I'm missing, but I can't find there's any "reload" like method in `HKHealthStore`, or any related options in `HKQuery/HKStatisticsQuery`. The code I'm using is quite straight forward as below. I wonder if there's any permissions or anything I'm missing. ``` let predicate = HKQuery.predicateForSamplesWithStartDate(date_start, endDate: NSDate(), options: HKQueryOptions.StrictStartDate) var type = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning) var query = HKStatisticsQuery(quantityType: type, quantitySamplePredicate: predicate, options: .CumulativeSum | .SeparateBySource, completionHandler: { query, stats, error in ( /*logs here*/ ) }) let healthStore = HKHealthStore() healthStore.executeQuery(query) ``` Edit: I also tried to write some data to `HealthKit` but the query doesn't get updated. Edit2: when I said "most recent steps counts" I meant something like: 1. execute HKQuery; 2. shake phone; 3. execute HKQuery again. Running the code above for 2 times and I always get the same results, but if I left Health.app or the `UP` app in the background, the latest query got the updated results. I also tried to call some other APIs like: ``` healthStore.enableBackgroundDeliveryForType(type, frequency:.Immediate, withCompletion:{ (success:Bool, error:NSError!) -> Void in let authorized = healthStore.authorizationStatusForType(type) LF.log("HEALTH callback success", success) LF.log("HEALTH callback authorized", type) }) if HKHealthStore.isHealthDataAvailable() == false { LF.log("HEALTH data not available") return } else { LF.log("HEALTH OK") } ``` For almost no reason but try to secretly "trigger" some sort of background refresh. But none of these attempts worked.

Original source