Watch OS 2.0 Beta:访问心率

27
使用Watch OS 2.0,开发人员应该可以访问心率传感器...我想玩一下并为我所拥有的想法建立一个简单的原型,但我找不到关于这个功能的信息或文档。请问有人能指导我如何完成这项任务吗?任何链接或信息都将不胜感激。

这个问题不是还在苹果的保密协议下吗?你应该去苹果开发者论坛问一下,对吧? - user4657588
@Dan 在开发者论坛上,我只能找到和我一样困惑的人... 我想也许这里的社区可以帮助我。 - Sr.Richie
足够远了。我猜苹果公司会在下一个watchOS 2.0测试版中改进它的文档。也许你可以提交一个错误报告? - user4657588
@丹,请查看:Moderators是否应强制执行软件供应商的保密协议(NDA)? 以及相关问题。SO的用户或版主无需监管其他方之间的NDA,这不是他们的责任。 - jscs
在探索 HealthKit 和 Watchkit 后,我在此链接中记录了一些观察结果:</br> https://dev59.com/TF4b5IYBdhLWcg3wojFg#33363644 - shoan
4个回答

35

苹果在watchOS 2.0中并没有技术上允许开发者访问心率传感器。它们提供的是对HealthKit传感器记录的心率数据的直接访问。要做到这一点并获取几乎实时的数据,您需要完成两件主要事情。首先,您需要告诉手表您正在开始一项锻炼(比如说您正在跑步):

// Create a new workout session
self.workoutSession = HKWorkoutSession(activityType: .Running, locationType: .Indoor)
self.workoutSession!.delegate = self;

// Start the workout session
self.healthStore.startWorkoutSession(self.workoutSession!)

然后,您可以从HKHealthKit开始流式查询,以便在HealthKit接收到更新时向您提供更新:

// This is the type you want updates on. It can be any health kit type, including heart rate.
let distanceType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning)

// Match samples with a start date after the workout start
let predicate = HKQuery.predicateForSamplesWithStartDate(workoutStartDate, endDate: nil, options: .None)

let distanceQuery = HKAnchoredObjectQuery(type: distanceType!, predicate: predicate, anchor: 0, limit: 0) { (query, samples, deletedObjects, anchor, error) -> Void in
    // Handle when the query first returns results
    // TODO: do whatever you want with samples (note you are not on the main thread)
}

// This is called each time a new value is entered into HealthKit (samples may be batched together for efficiency)
distanceQuery.updateHandler = { (query, samples, deletedObjects, anchor, error) -> Void in
    // Handle update notifications after the query has initially run
    // TODO: do whatever you want with samples (note you are not on the main thread)
}

// Start the query
self.healthStore.executeQuery(distanceQuery)

这些都在视频结尾的演示中有详细说明,What's New in HealthKit - WWDC 2015


所以基本上我在手表上开始会话,然后我可以在手机上查询,对吧?唯一的问题是数据只会每隔几分钟传输到我的手机,而不是每隔几秒钟... 我还在手机上使用了 enableBackgroundDeliveryForTypequantityTypeForIdentifier HKQuantityTypeIdentifierHeartRate,但这并没有改变任何事情... :( - Georg
从HKHealthKit启动一个流式查询。 这个查询是在手表上运行还是在手机上运行? 我可以在手表上开始锻炼并获取心率样本,但在手机上却得到空结果。 - Ashley Mills
2
查询是在手表上启动的,因为它具有心率传感器。Healthkit数据在手表上收集,并需要一些时间同步到手机上,但可以立即在手表上使用。 - lehn0058

6

您可以开始一项锻炼并从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{

__weak typeof(self) weakSelf = self;

//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。如果有任何问题,请在下面留言。


在模拟器中运行此代码,获取心率数据? - Sanandiya Vipul
模拟器将会给你结果。 - NeilNie
我这里遇到了如下错误=>>>error Error Domain=com.apple.healthkit Code=5 "Authorization request canceled" UserInfo={NSLocalizedDescription=Authorization request canceled} - Sanandiya Vipul
哦,是的,我忘了告诉你,在开始锻炼之前,你需要请求访问用户的健康数据。你需要代码吗? - NeilNie
我该怎么做? - Sanandiya Vipul
显示剩余3条评论

1
您可以使用HKWorkout,它是HealthKit框架的一部分。

0
现在很多iOS软件工具包也适用于watchOS,例如HealthKit。你可以使用HealthKit(HK)的函数和类来计算消耗的卡路里、查找心率等。你可以使用HKWorkout来计算关于锻炼的所有内容并访问相关变量,如心率,就像之前在iOS中一样。阅读苹果公司开发者文档以了解有关HealthKit的信息,这些文档可以在developer.apple.com上找到。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接