HealthCheck
Prerequisite( 预准备)
Enable HealthKit
如果希望在应用程序中使用

Check availability( 检查HealthKit 可用性)
考虑到目前
if(NSClassFromString(@"HKHealthStore") && [HKHealthStore isHealthDataAvailable])
{
// Add your HealthKit code here
}
Request authorization( 请求授权)
由于requestAuthorizationToShareTypes: readTypes: completion:
方法。
HKHealthStore *healthStore = [[HKHealthStore alloc] init];
// Share body mass, height and body mass index
NSSet *shareObjectTypes = [NSSet setWithObjects:
[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass],
[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight],
[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMassIndex],
nil];
// Read date of birth, biological sex and step count
NSSet *readObjectTypes = [NSSet setWithObjects:
[HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierDateOfBirth],
[HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierBiologicalSex],
[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount],
nil];
// Request access
[healthStore requestAuthorizationToShareTypes:shareObjectTypes
readTypes:readObjectTypes
completion:^(BOOL success, NSError *error) {
if(success == YES)
{
// ...
}
else
{
// Determine if it was an error or if the
// user just canceld the authorization request
}
}];
如上代码会调用下图这样的权限请求界面:

用户在该界面上可以选择接受或者拒绝某些对于读写健康数据的请求。在确定或者关闭请求界面之后,回调会被自动调用。
读写数据
从
生理数据
性别与年龄
NSError *error;
HKBiologicalSexObject *bioSex = [healthStore biologicalSexWithError:&error];
switch (bioSex.biologicalSex) {
case HKBiologicalSexNotSet:
// undefined
break;
case HKBiologicalSexFemale:
// ...
break;
case HKBiologicalSexMale:
// ...
break;
}
体重
// Some weight in gram
double weightInGram = 83400.f;
// Create an instance of HKQuantityType and
// HKQuantity to specify the data type and value
// you want to update
NSDate *now = [NSDate date];
HKQuantityType *hkQuantityType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
HKQuantity *hkQuantity = [HKQuantity quantityWithUnit:[HKUnit gramUnit] doubleValue:weightInGram];
// Create the concrete sample
HKQuantitySample *weightSample = [HKQuantitySample quantitySampleWithType:hkQuantityType
quantity:hkQuantity
startDate:now
endDate:now];
// Update the weight in the health store
[healthStore saveObject:weightSample withCompletion:^(BOOL success, NSError *error) {
// ..
}];
运动数据
运动数据查询时往往进行的是统计类型的查询,即查询某几个小时或者某几天的运动数据情况,此时最常用的工具类即是initWithQuantityType:quantitySamplePredicate:options:completionHandler:
方法进行初始化,然后使用executeQuery:方法进行查询。
步数与卡路里
- Objective-C
- (void)fetchTotalJoulesConsumedWithCompletionHandler:(void (^)(double, NSError *))completionHandler {
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *now = [NSDate date];
NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:now];
NSDate *startDate = [calendar dateFromComponents:components];
NSDate *endDate = [calendar dateByAddingUnit:NSCalendarUnitDay value:1 toDate:startDate options:0];
HKQuantityType *sampleType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryEnergyConsumed];
NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:startDate endDate:endDate options:HKQueryOptionStrictStartDate];
HKStatisticsQuery *query = [[HKStatisticsQuery alloc] initWithQuantityType:sampleType quantitySamplePredicate:predicate options:HKStatisticsOptionCumulativeSum completionHandler:^(HKStatisticsQuery *query, HKStatistics *result, NSError *error) {
if (!result) {
if (completionHandler) {
completionHandler(0.0f, error);
}
return;
}
double totalCalories = [result.sumQuantity doubleValueForUnit:[HKUnit jouleUnit]];
if (completionHandler) {
completionHandler(totalCalories, error);
}
}];
[self.healthStore executeQuery:query];
}
- Swift
func fetchTotalJoulesConsumedWithCompletionHandler(
completionHandler:(Double?, NSError?)->()) {
let calendar = NSCalendar.currentCalendar()
let now = NSDate()
let components = calendar.components(.YearCalendarUnit |
.MonthCalendarUnit | .DayCalendarUnit, fromDate: now)
let startDate = calendar.dateFromComponents(components)
let endDate = calendar.dateByAddingUnit(.DayCalendarUnit,
value: 1, toDate: startDate, options: NSCalendarOptions(nil))
let sampleType = HKQuantityType.quantityTypeForIdentifier(
HKQuantityTypeIdentifierDietaryEnergyConsumed)
let predicate = HKQuery.predicateForSamplesWithStartDate(startDate,
endDate: endDate, options: .StrictStartDate)
let query = HKStatisticsQuery(quantityType: sampleType,
quantitySamplePredicate: predicate,
options: .CumulativeSum) { query, result, error in
if result != nil {
completionHandler(nil, error)
return
}
var totalCalories = 0.0
if let quantity = result.sumQuantity() {
let unit = HKUnit.jouleUnit()
totalCalories = quantity.doubleValueForUnit(unit)
}
completionHandler(totalCalories, error)
}
healthStore.executeQuery(query)
}
注意,在根据时间来获取
startDate = [[NSDate alloc] initWithTimeIntervalSinceNow:- [endDate timeIntervalSinceDate:startDate]];
endDate = [[NSDate alloc] init];
CareKit
