iOS 健康 计步 卡路里

时间:2020-12-03 15:44:33

*注意:需要iOS8以上,调用前判断一下; 另外证书需要打开获取健康数据功能,自己百度。
获取健康数据,每天运动步数,实时获取。*

上代码:

//
// HealthManager.h
// zoubao
//
// Created by 李聪 on 15/4/20.
// Copyright (c) 2015年 李聪. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <HealthKit/HealthKit.h>

@interface HealthManager : NSObject

@property (nonatomic,strong) HKHealthStore *healthStore;


+(id)shareInstance;

/*!
* @author Lcong, 15-04-20 18:04:38
*
* @brief 获取当天实时步数
*
* @param handler 回调
*/

- (void)getRealTimeStepCountCompletionHandler:(void(^)(double value, NSError *error))handler;

/*!
* @author Lcong, 15-04-20 18:04:34
*
* @brief 获取一定时间段步数
*
* @param predicate 时间段
* @param handler 回调
*/

- (void)getStepCount:(NSPredicate *)predicate completionHandler:(void(^)(double value, NSError *error))handler;

/*!
* @author Lcong, 15-04-20 18:04:32
*
* @brief 获取卡路里
*
* @param predicate 时间段
* @param quantityType 样本类型
* @param handler 回调
*/

- (void)getKilocalorieUnit:(NSPredicate *)predicate quantityType:(HKQuantityType*)quantityType completionHandler:(void(^)(double value, NSError *error))handler;

/*!
* @author Lcong, 15-04-20 18:04:17
*
* @brief 当天时间段
*
* @return ,,,
*/

+ (NSPredicate *)predicateForSamplesToday;

@end
//
// HealthManager.m
// zoubao
//
// Created by 李聪 on 15/4/20.
// Copyright (c) 2015年 李聪. All rights reserved.
//

#import "HealthManager.h"
#import <UIKit/UIDevice.h>
#import "HKHealthStore+AAPLExtensions.h"

#define HKVersion [[[UIDevice currentDevice] systemVersion] doubleValue]
@implementation HealthManager

+(id)shareInstance
{
static id manager ;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[[self class] alloc] init];
[manager getPermissions];
});
return manager;
}

/*!
* @author Lcong, 15-04-20 17:04:44
*
* @brief 检查是否支持获取健康数据
*/

- (void)getPermissions
{
if(HKVersion >= 8.0)
{
if ([HKHealthStore isHealthDataAvailable]) {

if(self.healthStore == nil)
self.healthStore = [[HKHealthStore alloc] init];

/*
组装需要读写的数据类型
*/

NSSet *writeDataTypes = [self dataTypesToWrite];
NSSet *readDataTypes = [self dataTypesRead];

/*
注册需要读写的数据类型,也可以在“健康”APP中重新修改
*/

[self.healthStore requestAuthorizationToShareTypes:writeDataTypes readTypes:readDataTypes completion:^(BOOL success, NSError *error) {
if (!success) {
DebugLog(@"%@\n\n%@",error, [error userInfo]);
return ;
}
else
{
// dispatch_async(dispatch_get_main_queue(), ^{
// [self.window.rootViewController presentViewController:tabVC animated:YES completion:nil];
// });
}
}];
}
}
}

/*!
* @author Lcong, 15-04-20 16:04:42
*
* @brief 写权限
*
* @return 集合
*/

- (NSSet *)dataTypesToWrite
{
HKQuantityType *heightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight];
HKQuantityType *weightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
HKQuantityType *temperatureType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyTemperature];
HKQuantityType *activeEnergyType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned];

return [NSSet setWithObjects:heightType, temperatureType, weightType,activeEnergyType,nil];
}

/*!
* @author Lcong, 15-04-20 16:04:03
*
* @brief 读权限
*
* @return 集合
*/

- (NSSet *)dataTypesRead
{
HKQuantityType *heightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight];
HKQuantityType *weightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
HKQuantityType *temperatureType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyTemperature];
HKCharacteristicType *birthdayType = [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierDateOfBirth];
HKCharacteristicType *sexType = [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierBiologicalSex];
HKQuantityType *stepCountType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
HKQuantityType *activeEnergyType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned];

return [NSSet setWithObjects:heightType, temperatureType,birthdayType,sexType,weightType,stepCountType, activeEnergyType,nil];
}

/*!
* @author Lcong, 15-04-20 17:04:02
*
* @brief 实时获取当天步数
*/

- (void)getRealTimeStepCountCompletionHandler:(void(^)(double value, NSError *error))handler
{
if(HKVersion < 8.0)
{
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@"iOS 系统低于8.0" forKey:NSLocalizedDescriptionKey];
NSError *aError = [NSError errorWithDomain:CustomHealthErrorDomain code:0 userInfo:userInfo];
handler(0,aError);
}
else
{
HKSampleType *sampleType =
[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];

HKObserverQuery *query =
[[HKObserverQuery alloc]
initWithSampleType:sampleType
predicate:nil
updateHandler:^(HKObserverQuery *query,
HKObserverQueryCompletionHandler completionHandler,
NSError *error) {
if (error) {

// Perform Proper Error Handling Here...
DebugLog(@"*** An error occured while setting up the stepCount observer. %@ ***",
error.localizedDescription);
handler(0,error);
abort();
}
[self getStepCount:[HealthManager predicateForSamplesToday] completionHandler:^(double value, NSError *error) {
handler(value,error);
}];
}];
[self.healthStore executeQuery:query];
}
}

/*!
* @author Lcong, 15-04-20 17:04:03
*
* @brief 获取步数
*
* @param predicate 时间段
*/

- (void)getStepCount:(NSPredicate *)predicate completionHandler:(void(^)(double value, NSError *error))handler
{

if(HKVersion < 8.0)
{
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@"iOS 系统低于8.0" forKey:NSLocalizedDescriptionKey];
NSError *aError = [NSError errorWithDomain:CustomHealthErrorDomain code:0 userInfo:userInfo];
handler(0,aError);
}
else
{
HKQuantityType *stepType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];

[self.healthStore aapl_mostRecentQuantitySampleOfType:stepType predicate:predicate completion:^(NSArray *results, NSError *error) {
if(error)
{
handler(0,error);
}
else
{
NSInteger totleSteps = 0;
for(HKQuantitySample *quantitySample in results)
{
HKQuantity *quantity = quantitySample.quantity;
HKUnit *heightUnit = [HKUnit countUnit];
double usersHeight = [quantity doubleValueForUnit:heightUnit];
totleSteps += usersHeight;
}
DebugLog(@"当天行走步数 = %ld",totleSteps);
handler(totleSteps,error);
}
}];
}
}

/*!
* @author Lcong, 15-04-20 17:04:10
*
* @brief 当天时间段
*
* @return 时间段
*/

+ (NSPredicate *)predicateForSamplesToday {
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *now = [NSDate date];
NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:now];
[components setHour:0];
[components setMinute:0];
[components setSecond: 0];

NSDate *startDate = [calendar dateFromComponents:components];
NSDate *endDate = [calendar dateByAddingUnit:NSCalendarUnitDay value:1 toDate:startDate options:0];
NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:startDate endDate:endDate options:HKQueryOptionNone];
return predicate;
}

/*!
* @author Lcong, 15-04-20 17:04:38
*
* @brief 获取卡路里
*/

- (void)getKilocalorieUnit:(NSPredicate *)predicate quantityType:(HKQuantityType*)quantityType completionHandler:(void(^)(double value, NSError *error))handler
{

if(HKVersion < 8.0)
{
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@"iOS 系统低于8.0" forKey:NSLocalizedDescriptionKey];
NSError *aError = [NSError errorWithDomain:CustomHealthErrorDomain code:0 userInfo:userInfo];
handler(0,aError);
}
else
{
HKStatisticsQuery *query = [[HKStatisticsQuery alloc] initWithQuantityType:quantityType quantitySamplePredicate:predicate options:HKStatisticsOptionCumulativeSum completionHandler:^(HKStatisticsQuery *query, HKStatistics *result, NSError *error) {
HKQuantity *sum = [result sumQuantity];

double value = [sum doubleValueForUnit:[HKUnit kilocalorieUnit]];
DebugLog(@"%@卡路里 ---> %.2lf",quantityType.identifier,value);
if(handler)
{
handler(value,error);
}
}];
[self.healthStore executeQuery:query];
}
}


@end

其中HKHealthStore+AAPLExtensions 如下:

/*
Copyright (C) 2014 Apple Inc. All Rights Reserved.
See LICENSE.txt for this sample’s licensing information

Abstract:

Contains shared helper methods on HKHealthStore that are specific to Fit's use cases.

*/


@import HealthKit;

@interface HKHealthStore (AAPLExtensions)

// Fetches the single most recent quantity of the specified type.
- (void)aapl_mostRecentQuantitySampleOfType:(HKQuantityType *)quantityType predicate:(NSPredicate *)predicate completion:(void (^)(NSArray *results, NSError *error))completion;

@end
/*
Copyright (C) 2014 Apple Inc. All Rights Reserved.
See LICENSE.txt for this sample’s licensing information

Abstract:

Contains shared helper methods on HKHealthStore that are specific to Fit's use cases.

*/


#import "HKHealthStore+AAPLExtensions.h"

@implementation HKHealthStore (AAPLExtensions)

- (void)aapl_mostRecentQuantitySampleOfType:(HKQuantityType *)quantityType predicate:(NSPredicate *)predicate completion:(void (^)(NSArray *, NSError *))completion {
NSSortDescriptor *timeSortDescriptor = [[NSSortDescriptor alloc] initWithKey:HKSampleSortIdentifierEndDate ascending:NO];

// Since we are interested in retrieving the user's latest sample, we sort the samples in descending order, and set the limit to 1. We are not filtering the data, and so the predicate is set to nil.
HKSampleQuery *query = [[HKSampleQuery alloc] initWithSampleType:quantityType predicate:predicate limit:HKObjectQueryNoLimit sortDescriptors:@[timeSortDescriptor] resultsHandler:^(HKSampleQuery *query, NSArray *results, NSError *error) {
if (!results) {
if (completion) {
completion(nil, error);
}
return;
}

if (completion) {
// If quantity isn't in the database, return nil in the completion block.
NSLog(@"results ---- > = %@",results);
completion(results, error);
}
}];

[self executeQuery:query];
}

@end

这是哥哥我研究了几天英文文档才弄出来的(英文不好,痛苦死了),第一次写博客,就贡献了。

补充使用方法:

//倒入头文件 #import "HealthManager.h"

[[HealthManager shareInstance] getKilocalorieUnit:[HealthManager predicateForSamplesToday] quantityType:[HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned] completionHandler:^(double value, NSError *error) {
if(error)
{
DebugLog(@"error = %@",[error.userInfo objectForKey:NSLocalizedDescriptionKey]);
}
else
{
DebugLog(@"获取到的卡路里 = %.2lf",value);
}
}];

[[HealthManager shareInstance] getRealTimeStepCountCompletionHandler:^(double value, NSError *error) {

NSLog(@"当天行走步数 = %.2lf",value);
}];

其中对错误处理不够完善,项目刚开始,没多少时间去看,自己解决哈。

代码链接:http://download.csdn.net/detail/doing111/9296239