Reputation: 3281
In our app, we query the HealthKit for trailing 7 days' worth of step counts, summed daily, with a pivot of midnight. So the range is D-6 midnight until tomorrow's midnight (since we wanted today's steps until now).
Is that it works, and we are always able to get the past 6 day's data, except today's is always 0.
But the weird part is that, if we then open the default iHealth app that came with iOS 8.0, it calculates the health data and shows today's steps in the chart. And then, if we reopen our app and reload the chart data, today's steps is miraculously there, matching what "iHealth" shows.
So does iPhone automatically generate daily steps count only at midnight, and caches it or something? Is there a separate call we need to make in order to calculate today's data or something prior to retrieving any health metrics?
Here's the function we call to get the data:
func queryDailyStats(metric: NSString!, handler: ([NSDate: Int] -> Void)!) {
let quantityType = HKObjectType.quantityTypeForIdentifier(metric)
let calendar = NSCalendar.currentCalendar()
let now = NSDate()
let preservedComponents: NSCalendarUnit = (.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay)
let midnight: NSDate! = calendar.dateFromComponents(calendar.components(preservedComponents, fromDate:now))
let dailyInterval = NSDateComponents()
dailyInterval.day = 1
let tomorrow = calendar.dateByAddingUnit(.MonthCalendarUnit, value: 1, toDate: midnight, options: nil)
let oneMonthAgo = calendar.dateByAddingUnit(.MonthCalendarUnit, value: -1, toDate: midnight, options: nil)
let oneWeekAgo = calendar.dateByAddingUnit(.DayCalendarUnit, value: -6, toDate: midnight, options: nil) // only need to start from 6 days back
// need tomorrow's midnight as end date to get all of today's data
let predicate = HKQuery.predicateForSamplesWithStartDate(oneWeekAgo, endDate: tomorrow, options: .None)
let query = HKStatisticsCollectionQuery(
quantityType: quantityType,
quantitySamplePredicate: predicate,
options: .CumulativeSum,
anchorDate: midnight,
intervalComponents: dailyInterval
)
query.initialResultsHandler = { query, results, error -> Void in
var data:[NSDate: Int] = [:]
if error != nil {
println(error)
} else {
results.enumerateStatisticsFromDate(oneWeekAgo, toDate: midnight) { statistics, stop in
if let quantity = statistics.sumQuantity() {
let date = statistics.startDate
let value = Int(quantity.doubleValueForUnit(HKUnit.countUnit()))
data[date] = value
}
}
}
handler(data)
}
self.healthKitStore.executeQuery(query)
}
Upvotes: 3
Views: 2844
Reputation: 468
Try this code u just change the start date and End date.
-(void) getQuantityResult {
NSInteger limit = 0;
NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:currentDate endDate:[[NSDate date]dateByAddingTimeInterval:60*60*24*3] options:HKQueryOptionStrictStartDate];
NSString *endKey = HKSampleSortIdentifierEndDate;
NSSortDescriptor *endDate = [NSSortDescriptor sortDescriptorWithKey: endKey ascending: NO];
HKSampleQuery *query = [[HKSampleQuery alloc] initWithSampleType[HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]
predicate: predicate
limit: limit
sortDescriptors: @[endDate]
resultsHandler:^(HKSampleQuery *query, NSArray* results, NSError *error){
dispatch_async(dispatch_get_main_queue(), ^{
// sends the data using HTTP
int dailyAVG = 0;
for(HKQuantitySample *samples in results)
{
dailyAVG += [[samples quantity] doubleValueForUnit:[HKUnit countUnit]];
}
lblPrint.text = [NSString stringWithFormat:@"%d",dailyAVG];
NSLog(@"%@",lblPrint.text);
NSLog(@"%@",@"Done");
});
}];
[self.healthStore executeQuery:query];
}
Upvotes: 1
Reputation: 757
If you just want current or recent step count and distance data, you should use the Core Motion CMPedometer class instead of HealthKit. The interface is much easier and data is returned quickly and accurately. I had the same problem and switched to the Core Motion approach to solve it.
Upvotes: 1
Reputation: 360
Are you simply not enumerating it, or do you just not see the data? If the former, try changing results.enumerateStatisticsFromDate(oneWeekAgo, toDate: midnight)…
to results.enumerateStatisticsFromDate(oneWeekAgo, toDate: tomorrow)…
.
You probably also want to change your definition of tomorrow to be one day from midnight today, instead of one month!
Upvotes: 0
Reputation: 7353
Your query only has an initialResultsHandler. To get HealthKit to import steps from the motion co-processor more frequently when your app is running, you need to either set an updateHandler on this query or open an HKObserverQuery for steps.
Upvotes: 0