HealthKit 无法读取步数数据
HealthKit cannot read steps data
我正在使用 HealthKit 从我的 iOS 设备读取步数数据。
这是我的代码:
if ([HKHealthStore isHealthDataAvailable]) {
__block double stepsCount = 0.0;
self.healthStore = [[HKHealthStore alloc] init];
NSSet *stepsType =[NSSet setWithObject:[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]];
[self.healthStore requestAuthorizationToShareTypes:nil readTypes:stepsType completion:^(BOOL success, NSError * _Nullable error) {
if (success) {
HKSampleType *sampleType = [HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
HKSampleQuery *sampleQuery = [[HKSampleQuery alloc] initWithSampleType:sampleType predicate:nil limit:HKObjectQueryNoLimit sortDescriptors:nil resultsHandler:^(HKSampleQuery *query, NSArray *results, NSError *error) {
if (error != nil) {
NSLog(@"results: %lu", (unsigned long)[results count]);
for (HKQuantitySample *result in results) {
stepsCount += [result.quantity doubleValueForUnit:[HKUnit countUnit]];
}
NSLog(@"Steps Count: %f", stepsCount);
} else {
NSLog(@"error:%@", error);
}];
[self.healthStore executeQuery:sampleQuery];
[self.healthStore stopQuery:sampleQuery];
NSLog(@"steps:%f",stepsCount);
}
}];
}
我在 iPhone6 上构建并 运行 代码,它确实有步数数据,在设置 -> 隐私 -> 健康中,应用程序确实被允许读取数据,但是日志区只显示:
steps:0.000000
我在 for 循环和 NSLog(@"error:%@", error)
上设置了断点,但应用程序没有中断。
有人可以帮忙吗?
您的代码在有机会 运行 之前立即停止查询。对于此查询,根本没有理由调用 stopQuery:
除非您想在查询完成前取消它。由于查询不是长期存在的(它没有 updateHandler
),它将在调用 resultsHandler
后立即停止。
第二个问题是您的代码过早地尝试记录步数。查询 运行 是异步的,查询完成后 resultsHandler
将在后台线程上调用。我建议在块内记录 stepsCount
。
最后,如果您想计算用户的步数,您应该使用 HKStatisticsQuery
而不是对 HKSampleQuery
的结果求和。当 HealthKit 中有多个重叠数据源时,HKStatisticsQuery
更有效并且会产生正确的结果。例如,如果用户同时拥有 iPhone 和 Apple Watch,您当前的实施将重复计算用户的步数。
试试这个代码,你只需更改开始日期和结束日期。
-(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];
}
我正在使用 HealthKit 从我的 iOS 设备读取步数数据。
这是我的代码:
if ([HKHealthStore isHealthDataAvailable]) {
__block double stepsCount = 0.0;
self.healthStore = [[HKHealthStore alloc] init];
NSSet *stepsType =[NSSet setWithObject:[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]];
[self.healthStore requestAuthorizationToShareTypes:nil readTypes:stepsType completion:^(BOOL success, NSError * _Nullable error) {
if (success) {
HKSampleType *sampleType = [HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
HKSampleQuery *sampleQuery = [[HKSampleQuery alloc] initWithSampleType:sampleType predicate:nil limit:HKObjectQueryNoLimit sortDescriptors:nil resultsHandler:^(HKSampleQuery *query, NSArray *results, NSError *error) {
if (error != nil) {
NSLog(@"results: %lu", (unsigned long)[results count]);
for (HKQuantitySample *result in results) {
stepsCount += [result.quantity doubleValueForUnit:[HKUnit countUnit]];
}
NSLog(@"Steps Count: %f", stepsCount);
} else {
NSLog(@"error:%@", error);
}];
[self.healthStore executeQuery:sampleQuery];
[self.healthStore stopQuery:sampleQuery];
NSLog(@"steps:%f",stepsCount);
}
}];
}
我在 iPhone6 上构建并 运行 代码,它确实有步数数据,在设置 -> 隐私 -> 健康中,应用程序确实被允许读取数据,但是日志区只显示:
steps:0.000000
我在 for 循环和 NSLog(@"error:%@", error)
上设置了断点,但应用程序没有中断。
有人可以帮忙吗?
您的代码在有机会 运行 之前立即停止查询。对于此查询,根本没有理由调用 stopQuery:
除非您想在查询完成前取消它。由于查询不是长期存在的(它没有 updateHandler
),它将在调用 resultsHandler
后立即停止。
第二个问题是您的代码过早地尝试记录步数。查询 运行 是异步的,查询完成后 resultsHandler
将在后台线程上调用。我建议在块内记录 stepsCount
。
最后,如果您想计算用户的步数,您应该使用 HKStatisticsQuery
而不是对 HKSampleQuery
的结果求和。当 HealthKit 中有多个重叠数据源时,HKStatisticsQuery
更有效并且会产生正确的结果。例如,如果用户同时拥有 iPhone 和 Apple Watch,您当前的实施将重复计算用户的步数。
试试这个代码,你只需更改开始日期和结束日期。
-(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];
}