最近在項目中遇到HealthKit的數據獲取相關的問題,對此作了一些簡單的封裝,以便于以后相似需求時便于調用。
相關類庫的準備HealthKit
首先你需要了解對象的結構
-
HKObjectType用于處理項目中需要的項目類。
462A23A7-BBFE-4000-957B-315CF124B731.png
HKObjectType大概分成以上幾類,構建需求請求的時候需要嚴格按照類型來存儲的 -
HKTypeIdentifiers用于處理項目中你所需要獲取的數據的類型。
325E0E84-F99A-43CF-9FFF-CFA2DB9186D1.png
一般來說我們所獲取的數值是count,distance之類的,全局搜索可以便于找到你需要的值。 -
HKUnit獲取完類別以后呢,我們需要查詢這個類別對應的單位(Unit)。這個分類下的值的單位(米,千米之類的)
3D4E36E6-CC42-418D-A027-49F50D830868.png - HKSampleQuery用來 查詢數據對象。
- HKSample查詢出來的結果。
代碼實踐
//查看healthKit在設備上是否可用,ipad不支持HealthKit
if(![HKHealthStore isHealthDataAvailable]) {
NSLog(@"設備不支持healthKit");
return;
}
//創建healthStore實例對象
self.healthStore = [[HKHealthStore alloc] init];
NSMutableSet *healthSet = [NSMutableSet set];HKQuantityType
HKObjectType *stepCount = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
[healthSet addObject:stepCount];HKCategoryType
HKObjectType *standHour = [HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierAppleStandHour];
[healthSet addObject:standHour];HKWorkoutType
HKObjectType *workout = [HKObjectType workoutType]
[healthSet addObject:workout];
//從健康應用中獲取權限
[self.healthStore requestAuthorizationToShareTypes:nil readTypes:healthSet completion:^(BOOL success, NSError * _Nullable error) {
if (success) {
NSLog(@"獲取步數權限成功");
//在這里去獲取數據
} else {
NSLog(@"獲取權限失敗");
}
}];獲取數據類型,注意不同數據類型的數據獲取方式是不一樣的
HKSampleType *sampleType;
要注意獲取的數據是分段的,比如你一天走10000步,可能有幾百條數據,在獲取每天的站立時間時發現,每一個小時是一個數據,鍛煉分鐘數是每一個分鐘,在實際用這個數據時,應該合理控制數據
NSInteger limitNumber = 1000;
NSSortDescriptor *start = [NSSortDescriptor >sortDescriptorWithKey:HKSampleSortIdentifierStartDate ascending:NO];
NSSortDescriptor *end = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierEndDate ascending:NO];
__weak typeof(self) weakSelf = self;
HKSampleQuery *sampleQuery = [[HKSampleQuery alloc] initWithSampleType:sampleType predicate:nil limit:limitNumber sortDescriptors:@[start,end] resultsHandler:^(HKSampleQuery * _Nonnull query, NSArray<__kindof HKSample *> * _Nullable results, NSError * _Nullable error) {
@autoreleasepool {
for (HKSample *result in results){
針對不同子類的result進行處理數據
在判斷結果的開始時間和結束時間,是否是自己需要的那天的數據
}
}
//回到主線程
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
//數據刷新
}];
}];
//執行查詢
[self.healthStore executeQuery:sampleQuery];
注意點
不同HKSample實例的數據的獲取方式方法是不一樣的
//HKQuantitySample的子類數據,獲取result.quantity,根據quantity獲取數值
//HKCategorySample的子類數據,獲取的是result.value的值,在獲取站立小時數時發現,當value值是1的時候,反而是靜歇時的數據,這里需要注意
//HKWorkout的子類數據,鍛煉時間數,大概有duration,totalEnergyBurned,totalDistance,totalSwimmingStrokeCount這些值來處理
不同數據來源的數據是不一樣的
HKSample 的父類 HKObject有source(8.0以上)和device(9.0以上)倆個字段來判斷來源。這邊需要注意的是多個數據來源的數據。不要一味的全部相加。