Watch os 2.0 beta: access heart beat rate

13,780

Solution 1

Apple isn't technically giving developers access to the heart rate sensors in watchOS 2.0. What they are doing is providing direct access to heart rate data recorded by the sensor in HealthKit. To do this and get data in near-real time, there are two main things you need to do. First, you need to tell the watch that you are starting a workout (lets say you are running):

// 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!)

Then, you can start a streaming query from HKHealthKit to give you updates as HealthKit receives them:

// 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)

This is all described in full detail in the demo at the end of the video What's New in HealthKit - WWDC 2015

Solution 2

You can get heart rate data by starting a workout and query heart rate data from healthkit.

Ask for premission for reading workout data.

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);
    }
}];

In AppDelegate on iPhone, respond this this request

-(void)applicationShouldRequestHealthAuthorization:(UIApplication *)application{

[healthStore handleAuthorizationForExtensionWithCompletion:^(BOOL success, NSError * _Nullable error) {
    if (success) {
        NSLog(@"phone recieved health kit request");
    }
}];
}

Then implement 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;
}
});
}

Now it's time to write [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];
}

You also have a turn on Healthkit in capbilities. Leave a comment below if you have any questions.

Solution 3

You may use HKWorkout, which is part of the HealthKit framework.

Share:
13,780

Related videos on Youtube

Sr.Richie
Author by

Sr.Richie

AS3, Arduino, Processing, Objective-C, AngularJS

Updated on June 04, 2022

Comments

  • Sr.Richie
    Sr.Richie almost 2 years

    With Watch OS 2.0 developers are supposed to be allowed to access heart beat sensors.... I would love to play a bit with it and build a simple prototype for an idea I have, but I can't find anywhere info or documentation about this feature.

    Can anyone point me on how to approach this task? Any link or info would be appreciated

    • Admin
      Admin almost 9 years
      Isn't this still under NDA by Apple, you should ask this on the Apple developer forums no?
    • Sr.Richie
      Sr.Richie almost 9 years
      @Dan in the devs forum I could only find people as confused as me.... I thought that maybe the community here could help
    • Admin
      Admin almost 9 years
      Ah far enough. I guess Apple will improve its documentation as the next watchOS 2.0 betas are released. Maybe you could submit a bug report?
    • jscs
      jscs almost 9 years
      @Dan, please see: Should moderators enforce NDAs for software vendors? and related questions. It is not the responsibility of SO users or moderators to police NDAs between other parties.
    • shoan
      shoan over 8 years
      After exploring HealthKit and Watchkit I have a few observations noted at this link</br> stackoverflow.com/a/33363644/591811
  • Georg
    Georg over 8 years
    So basically I start the session on the watch and then I could query on the Phone, right? The only problem is that data is transferred to my phone only every few minutes instead of every few seconds... I also did enableBackgroundDeliveryForType with quantityTypeForIdentifier HKQuantityTypeIdentifierHeartRate on the phone but that didn't change anything... :(
  • Sanandiya Vipul
    Sanandiya Vipul almost 8 years
    in Simulator Run this Code and Get Heart rate on it ?
  • NeilNie
    NeilNie almost 8 years
    The simulator will give you results.
  • Sanandiya Vipul
    Sanandiya Vipul almost 8 years
    Here i am getting this Error=>>>error Error Domain=com.apple.healthkit Code=5 "Authorization request canceled" UserInfo={NSLocalizedDescription=Authorization request canceled}
  • NeilNie
    NeilNie almost 8 years
    Oh yeah I forgot to tell you that you need to request access to users health data before you start the workout. Do you want the code ?
  • Sanandiya Vipul
    Sanandiya Vipul almost 8 years
    how can i do this ?
  • NeilNie
    NeilNie almost 8 years
    In the first part of my answer, I have also explained how you should request for user permission. You should implement this either in ExtensionDelegate or willActivate method.
  • Sanandiya Vipul
    Sanandiya Vipul almost 8 years
  • NeilNie
    NeilNie almost 8 years
    Sure, give me 2 hours
  • Ashley Mills
    Ashley Mills about 7 years
    "start a streaming query from HKHealthKit " is this query running on the watch or on the phone? I can start a workout and get heart-rate samples on the watch, but on the phone I get an empty results.
  • lehn0058
    lehn0058 about 7 years
    The query is started on the watch, since it has the heart rate sensor. Healthkit data is collected on the watch and takes some time to sync over to the phone, but is available right away on the watch.