想要做HealthKit,电脑上安装的profile的APP ID 必须包含HealthKit服务。
先来做个测试的。
在developer中新建一个App ID,
选择App ID Suffix —> Explicit APP ID ,一定要输入全名的,不能带*号 —> APP services, 这里一定要勾选 HealthKit,剩下的根据所需一直continue。
然后新建一个作为developer 用的 profile, app id 选刚才新建的那个带有HealthKit的然后按需continue,最后下载下来安装上。
在Xcode中新建一个空工程,先导入HealthKit.framework这个库
打开新工程的targets,在Capabilities中找到
当然刚开始的时候是关闭状态,你要打开它,然后选择下面的 Fix使得上面几项都为“√”
这时候会在目录树中看到:
这说明已经申请成功了Healthkit服务。
在使用服务前,要先检查设备是否支持HealthKit服务
if ([HKHealthStore isHealthDataAvailable]) {
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) {
NSLog(@"%@\n\n%@",error, [error userInfo]);
return ;
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.window.rootViewController presentViewController:tabVC animated:YES completion:nil];
});
}
}];
}
- (NSSet *)dataTypesToWrite
{
HKQuantityType *heightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight];
HKQuantityType *weightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
HKQuantityType *temperatureType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyTemperature];
return [NSSet setWithObjects:heightType, temperatureType, weightType, nil];
}
- (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];
return [NSSet setWithObjects:heightType, temperatureType,birthdayType,sexType,weightType, nil];
}
如果正常的情况,会在启动的时候弹出一个窗口提示请求服务
可以提示用户自己选择同意APP读写的数据类型。
一般数据的保存:
- (void)saveTemperatureIntoHealthStore:(double)temperature
{
/*
要保存的数据类型
对于温度、体重都有不同的显示方式
比如温度:
@interface HKUnit (Temperature)
+ (instancetype)degreeCelsiusUnit; // degC
+ (instancetype)degreeFahrenheitUnit; // degF
+ (instancetype)kelvinUnit; // K
@end
*/
HKUnit *temperatureUnit;
if (_unitSeg.selectedSegmentIndex == 0)
{
temperatureUnit = [HKUnit degreeCelsiusUnit];
}
else
{
temperatureUnit = [HKUnit degreeFahrenheitUnit];
}
/*
HKQuantity 将要保存的数据转换成 HealthKit 中通用的数据模型
*/
HKQuantity *temperatureQuantity = [HKQuantity quantityWithUnit:temperatureUnit doubleValue:temperature];
/*
HKQuantityType 要将HKQuantity保存到的健康数据类型,比如体温、体重、身高等…………
*/
HKQuantityType *temperatureType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyTemperature];
/*
保存数据的时间,开始和结束,为了实时保存就都为同一个时间
*/
NSDate *date = [NSDate date];
HKQuantitySample *temperatureSample = [HKQuantitySample quantitySampleWithType:temperatureType quantity:temperatureQuantity startDate:date endDate:date];
/*
调用 apple 的接口保存数据
*/
[SHAREAPP.healthStore saveObject:temperatureSample withCompletion:^(BOOL success, NSError *error) {
if (!success)
{
NSLog(@"\n**************************\n %@ \n\n%@\n\n%@\n**************************",NSStringFromSelector(_cmd),error, [error userInfo]);
abort();
}
else
[self updateUserTemperature];
}];
}
对于生理性别、生日、血型,则不能让用户写入,只提供读取操作。
对于出生日期的读取,只是一句话,然后需要自己计算
NSError *error;
NSDate *dateOfBirth = [SHAREAPP.healthStore dateOfBirthWithError:&error];
对于性别的 读取
NSError *error ;
HKBiologicalSexObject *sexObject = [SHAREAPP.healthStore biologicalSexWithError:&error];
使用
sexObject.biologicalSex
获取性别信息,这是一个枚举值
typedef NS_ENUM(NSInteger, HKBiologicalSex) {
HKBiologicalSexNotSet = 0,
HKBiologicalSexFemale,
HKBiologicalSexMale,
} NS_ENUM_AVAILABLE_IOS(8_0);
对于其他数据的读取
需要提供读取的生理数据类型
HKQuantityType *weightType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
然后直接类似的coredata的query
- (void)appl_mostRecentQuantitySampleOfType:(HKQuantityType *)quantityType predicate:(NSPredicate *)predicate completions:(void (^)(NSArray *, NSError *))completion
{
NSSortDescriptor *timeSortDescriptor = [[NSSortDescriptor alloc] initWithKey:HKSampleSortIdentifierEndDate ascending:NO];
HKSampleQuery *query = [[HKSampleQuery alloc] initWithSampleType:quantityType predicate:nil limit:HKObjectQueryNoLimit sortDescriptors:@[timeSortDescriptor] resultsHandler:^(HKSampleQuery *query, NSArray *results, NSError *error) {
if (!results)
{
if (completion)
{
completion(nil, error);
}
return ;
}
if (completion)
{
completion(results, error);
}
}];
[self executeQuery:query];
}
返回的数组中都是 HKQuantitySample 类型的生理数据的实例,包含着数据的类型和这个数据的量值与计量单位(HKQuantity)
HKQuantity数据不能直接使用,需要进行转换。
先定义一个数据类型:
HKUnit *heightUnit = [HKUnit inchUnit];
然后转换
double usersHeight = [quantity doubleValueForUnit:heightUnit];
此时的数据就能按需来正常使用了。
但是需要注意的是:
在保存的时候注意数据的单位,读的时候更要注意。