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:
Health.app
, keep it running in background, and do the test again in my app;UP app
, keep it running in background, and do the test again in my app.And if I force-quit the Health.app
orUP 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With