我们可以直接从 Apple Watch 访问 HealthKit 心率吗?
我知道这是一个重复的问题,但 5 个月内没有人问过这个问题。我知道您可以从健康应用程序访问它,但我不确定它有多“实时”。
心率原始数据信息现在可用在
Watchkit for watchOS 2.0
中。
WatchOS 2
包括对其他现有框架(例如 HealthKit
)的许多增强功能,可以访问实时获取心率和健康信息的健康传感器。
您可以在接下来的总共30分钟的演示中查看这些信息。如果您不想观看整个会议,那么您可以直接跳到
Healthkit API
功能,该功能在25-28分钟之间:
WWDC 2015 中针对 watchOS 2.0 的 WatchKit 会议
这里是源码实现链接
如HKWorkout 课程参考中所述:
类是HKWorkout
类的具体子类。HKSample
使用锻炼来跟踪各种活动。这 锻炼对象不仅存储有关活动的摘要信息 (例如,持续时间、总距离和燃烧的总能量) 也可用作其他样品的容器。您可以关联任何 锻炼的样本数量。这样就可以添加详细的 与锻炼相关的信息。HealthKit
在给定的链接中,代码的以下部分定义了 heartRate 的采样率
NSMutableArray *samples = [NSMutableArray array];
HKQuantity *heartRateForInterval =
[HKQuantity quantityWithUnit:[HKUnit unitFromString:@"count/min"]
doubleValue:95.0];
HKQuantitySample *heartRateForIntervalSample =
[HKQuantitySample quantitySampleWithType:heartRateType
quantity:heartRateForInterval
startDate:intervals[0]
endDate:intervals[1]];
[samples addObject:heartRateForIntervalSample];
正如他们所说:
您需要微调相关样本的准确长度 根据锻炼类型和应用程序的需求。使用5分钟 间隔最大限度地减少了存储锻炼所需的内存量, 同时仍然提供强度变化的总体感觉 长时间锻炼的过程。使用 5 秒间隔可提供 更详细的锻炼视图,但需要更多 记忆和处理。
探索 HealthKit 和 WatchKit Extension 后,我的发现如下:
我们不需要WatchKit扩展来获取心率数据。
你只需要一部 iPhone 和配对的 Apple Watch(这是显而易见的)
默认的 Apple Watch 心率监测应用程序仅在前台运行时才会立即更新 HealthKit 数据。
当默认 Apple Watch 心率监测器应用程序处于后台时,它会以 9-10 分钟的间隔更新 HealthKit 数据。
要从 HealthKit 获取心率数据,需要定期触发以下查询。
func getSamples() {
let heathStore = HKHealthStore()
let heartrate = HKQuantityType.quantityType(forIdentifier: .heartRate)
let sort: [NSSortDescriptor] = [
.init(key: HKSampleSortIdentifierStartDate, ascending: false)
]
let sampleQuery = HKSampleQuery(sampleType: heartrate!, predicate: nil, limit: 1, sortDescriptors: sort, resultsHandler: resultsHandler)
heathStore.execute(sampleQuery)
}
func resultsHandler(query: HKSampleQuery, results: [HKSample]?, error: Error?) {
guard error == nil else {
print("cant read heartRate data", error!)
return
}
guard let sample = results?.first as? HKQuantitySample else { return }
// let heartRateUnit: HKUnit = .init(from: "count/min")
// let doubleValue = sample.quantity.doubleValue(for: heartRateUnit)
print("heart rate is", sample)
}
如果有人获得更多信息,请更新我。
快乐编码。
更新
我已将您的代码更新为清晰通用,请注意,您需要获得读取 HeathKit 数据并添加
info.plist
键 Privacy - Health Records Usage Description
的授权
无法直接访问 Apple Watch 上的任何传感器。您将必须依赖 HealthKit 的访问。
一位苹果布道者这样说
目前无法创建心脏监测器应用程序。这 数据不保证实时发送到 iPhone,因此您不会 能够及时确定正在发生的事情。
您可以通过开始锻炼来获取心率数据,并从healthkit中查询心率数据。
请求允许读取锻炼数据。
HKHealthStore *healthStore = [[HKHealthStore alloc] init];
HKQuantityType *type = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate];
HKQuantityType *type2 = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierDistanceWalkingRunning];
HKQuantityType *type3 = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned];
[healthStore requestAuthorizationToShareTypes:nil readTypes:[NSSet setWithObjects:type, type2, type3, nil] completion:^(BOOL success, NSError * _Nullable error) {
if (success) {
NSLog(@"health data request success");
}else{
NSLog(@"error %@", error);
}
}];
在 iPhone 上的 AppDelegate 中,响应此请求
-(void)applicationShouldRequestHealthAuthorization:(UIApplication *)application{
[healthStore handleAuthorizationForExtensionWithCompletion:^(BOOL success, NSError * _Nullable error) {
if (success) {
NSLog(@"phone recieved health kit request");
}
}];
}
然后实施
Healthkit Delegate
:
-(void)workoutSession:(HKWorkoutSession *)workoutSession didFailWithError:(NSError *)error{
NSLog(@"session error %@", error);
}
-(void)workoutSession:(HKWorkoutSession *)workoutSession didChangeToState:(HKWorkoutSessionState)toState fromState:(HKWorkoutSessionState)fromState date:(NSDate *)date{
dispatch_async(dispatch_get_main_queue(), ^{
switch (toState) {
case HKWorkoutSessionStateRunning:
//When workout state is running, we will excute updateHeartbeat
[self updateHeartbeat:date];
NSLog(@"started workout");
break;
default:
break;
}
});
}
现在是时候写了
**[self updateHeartbeat:date]**
-(void)updateHeartbeat:(NSDate *)startDate{
//first, create a predicate and set the endDate and option to nil/none
NSPredicate *Predicate = [HKQuery predicateForSamplesWithStartDate:startDate endDate:nil options:HKQueryOptionNone];
//Then we create a sample type which is HKQuantityTypeIdentifierHeartRate
HKSampleType *object = [HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate];
//ok, now, create a HKAnchoredObjectQuery with all the mess that we just created.
heartQuery = [[HKAnchoredObjectQuery alloc] initWithType:object predicate:Predicate anchor:0 limit:0 resultsHandler:^(HKAnchoredObjectQuery *query, NSArray<HKSample *> *sampleObjects, NSArray<HKDeletedObject *> *deletedObjects, HKQueryAnchor *newAnchor, NSError *error) {
if (!error && sampleObjects.count > 0) {
HKQuantitySample *sample = (HKQuantitySample *)[sampleObjects objectAtIndex:0];
HKQuantity *quantity = sample.quantity;
NSLog(@"%f", [quantity doubleValueForUnit:[HKUnit unitFromString:@"count/min"]]);
}else{
NSLog(@"query %@", error);
}
}];
//wait, it's not over yet, this is the update handler
[heartQuery setUpdateHandler:^(HKAnchoredObjectQuery *query, NSArray<HKSample *> *SampleArray, NSArray<HKDeletedObject *> *deletedObjects, HKQueryAnchor *Anchor, NSError *error) {
if (!error && SampleArray.count > 0) {
HKQuantitySample *sample = (HKQuantitySample *)[SampleArray objectAtIndex:0];
HKQuantity *quantity = sample.quantity;
NSLog(@"%f", [quantity doubleValueForUnit:[HKUnit unitFromString:@"count/min"]]);
}else{
NSLog(@"query %@", error);
}
}];
//now excute query and wait for the result showing up in the log. Yeah!
[healthStore executeQuery:heartQuery];
}
您还可以在功能中打开 Healthkit。如果您有任何疑问,请在下面发表评论。