问题
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
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.
回答1:
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.
来源:https://stackoverflow.com/questions/27223353/how-to-force-a-hkquery-to-load-the-most-recent-steps-counts