IOS HealthKit today step count is always 0 (but end days are ok)
In our application, we request HealthKit to keep track of 7 days counters, summed daily, with a midnight point. So the range is D-6 midnight to midnight tomorrow (as we wanted the steps today so far).
This is what it works and we can always get the latest 6 days of data, except that it is always 0 today.
But the weird part is that if we open the default iHealth app that ships with iOS 8.0, it calculates the health data and shows today's steps in a graph. And then if we reopen our app and reload the chart data, today the steps there miraculously match what "iHealth" shows.
So the iPhone only generates daily counts automatically at midnight and caches it or something? Is there a separate challenge we need to make in order to calculate today's data or something before any health indicators are obtained?
Here's the function we're calling 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 midnight as end date to get all of today 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)
}
source to share
Try this code and just change 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];
}
source to share
Are you just not listing it, or are you just not seeing the data? If the former, try changing results.enumerateStatisticsFromDate(oneWeekAgo, toDate: midnight)…
to results.enumerateStatisticsFromDate(oneWeekAgo, toDate: tomorrow)…
.
You might also want to change your definition of tomorrow by one day from midnight today, not a month!
source to share
If you just want current or recent stride and distance data, you should use the CMPedometer Core Motion class instead of HealthKit. The interface is much simpler and data is returned quickly and accurately. I had the same problem and switched to the Core Motion approach to solve this problem.
source to share