Reputation: 147
I am calling a function and have been trying to figure out how I can update my app to reflect the total steps for the day. Currently, the code I have only gives me the most recent quantity of steps that has been recorded. I am having trouble understanding how to use the HKStatisticsQuery
but this is the function I have at the moment that is giving me the most recent results.
-(void)updateStepsLabel{
// Query to get the user's latest steps, if it exists.
HKQuantityType *stepsType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
[_healthStore aapl_mostRecentQuantitySampleOfType:stepsType predicate:nil completion:^(HKQuantity *mostRecentQuantity, NSError *error) {
if (!mostRecentQuantity) {
NSLog(@"Either an error occured fetching the user's steps information or none has been stored yet. In your app, try to handle this gracefully.");
dispatch_async(dispatch_get_main_queue(), ^{
self.todaysStepValueLabel.text = NSLocalizedString(@"Not available", nil);
});
}
else {
// Determine the steps in the required unit.
HKUnit *stepUnit = [HKUnit countUnit];
double usersWeight = [mostRecentQuantity doubleValueForUnit:stepUnit];
// Update the user interface.
dispatch_async(dispatch_get_main_queue(), ^{
self.todaysStepValueLabel.text = [NSNumberFormatter localizedStringFromNumber:@(usersWeight) numberStyle:NSNumberFormatterNoStyle];
self.todaysStepValueLabel.textColor = [UIColor blackColor];
self.todaysStepValueLabel.font = [UIFont systemFontOfSize:25];
});
}
}];
}
Upvotes: 1
Views: 2279
Reputation: 5039
Here I am posting an answer with Swift code, I hope you would be able to convert it into Obj-c
I have written the below function in a class with definition like this
class MyHealthStore: HKHealthStore { }
.
func TodayTotalSteps(completion: (stepRetrieved: Double) -> Void) {
let type = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount) // The type of data we are requesting
let calendar = NSCalendar.currentCalendar()
let interval = NSDateComponents()
interval.day = 1
let anchorComponents = calendar.components([.Day , .Month , .Year], fromDate: NSDate())
anchorComponents.hour = 0
let anchorDate = calendar.dateFromComponents(anchorComponents)
let stepsQuery = HKStatisticsCollectionQuery(quantityType: type!, quantitySamplePredicate: nil, options: .CumulativeSum, anchorDate: anchorDate!, intervalComponents: interval)
stepsQuery.initialResultsHandler = {query, results, error in
let endDate = NSDate()
var totalSteps = 0.0
let startDate = calendar.dateByAddingUnit(.Day, value: 0, toDate: endDate, options: [])
if let myResults = results{ myResults.enumerateStatisticsFromDate(startDate!, toDate: endDate) { statistics, stop in
if let quantity = statistics.sumQuantity(){
//let date = statistics.startDate
totalSteps = quantity.doubleValueForUnit(HKUnit.countUnit())
// print("\(date): steps = \(steps)")
}
self.todayManuallyAddedSteps({ (manuallSteps, error) in
if error != nil {
print(error)
} else {
totalSteps = totalSteps - manuallSteps
completion(stepRetrieved: totalSteps)
return
}
})
//completion(stepRetrieved: totalSteps)
}
} else {
// mostly not executed
completion(stepRetrieved: totalSteps)
}
}
executeQuery(stepsQuery)
}
And if you want to truncate manually added steps use this function
func todayManuallyAddedSteps(completion: (Double, NSError?) -> () )
{
let type = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount) // The type of data we are requesting
let date = NSDate()
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let newDate = cal.startOfDayForDate(date)
let predicate = HKQuery.predicateForSamplesWithStartDate(newDate, endDate: NSDate(), options: .None) // Our search predicate which will fetch all steps taken today
// The actual HealthKit Query which will fetch all of the steps and add them up for us.
let query = HKSampleQuery(sampleType: type!, predicate: predicate, limit: 0, sortDescriptors: nil) { query, results, error in
var steps: Double = 0
if results?.count > 0
{
for result in results as! [HKQuantitySample]
{
// checking and adding manually added steps
if result.sourceRevision.source.name == "Health" {
// these are manually added steps
steps += result.quantity.doubleValueForUnit(HKUnit.countUnit())
}
else{
// these are auto detected steps which we do not want from HKSampleQuery
}
}
completion(steps, error)
return
} else {
// mostly not executed
completion(steps, error)
}
}
executeQuery(query)
}
and here is how to call it
MyHealthStore.sharedHealthStore.TodayTotalSteps { (stepRetrieved) in
print(stepRetrieved)
}
I hope its helps, let me know if you find any difficulty.
Upvotes: 1
Reputation: 11127
Here is the code which is given in the document of HKStatisticsCollectionQuery
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *interval = [[NSDateComponents alloc] init];
interval.day = 7;
// Set the anchor date to Monday at 3:00 a.m.
NSDateComponents *anchorComponents =
[calendar components:NSCalendarUnitDay | NSCalendarUnitMonth |
NSCalendarUnitYear | NSCalendarUnitWeekday fromDate:[NSDate date]];
NSInteger offset = (7 + anchorComponents.weekday - 2) % 7;
anchorComponents.day -= offset;
anchorComponents.hour = 3;
NSDate *anchorDate = [calendar dateFromComponents:anchorComponents];
HKQuantityType *quantityType =
[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
// Create the query
HKStatisticsCollectionQuery *query =
[[HKStatisticsCollectionQuery alloc]
initWithQuantityType:quantityType
quantitySamplePredicate:nil
options:HKStatisticsOptionCumulativeSum
anchorDate:anchorDate
intervalComponents:interval];
// Set the results handler
query.initialResultsHandler =
^(HKStatisticsCollectionQuery *query, HKStatisticsCollection *results, NSError *error) {
if (error) {
// Perform proper error handling here
NSLog(@"*** An error occurred while calculating the statistics: %@ ***",
error.localizedDescription);
abort();
}
NSDate *endDate = [NSDate date];
NSDate *startDate = [calendar
dateByAddingUnit:NSCalendarUnitMonth
value:-3
toDate:endDate
options:0];
// Plot the weekly step counts over the past 3 months
[results
enumerateStatisticsFromDate:startDate
toDate:endDate
withBlock:^(HKStatistics *result, BOOL *stop) {
HKQuantity *quantity = result.sumQuantity;
if (quantity) {
NSDate *date = result.startDate;
double value = [quantity doubleValueForUnit:[HKUnit countUnit]];
// Call a custom method to plot each data point.
[self plotWeeklyStepCount:value forDate:date];
}
}];
};
[self.healthStore executeQuery:query];
In the given code there are 2 dates mentioned
NSDate *endDate = [NSDate date];
NSDate *startDate = [calendar
dateByAddingUnit:NSCalendarUnitMonth
value:-3
toDate:endDate
options:0];
Change the startDate and endDate as per your requirement.
Upvotes: 0