iOS HealthKit how to save Heart Rate (bpm) values?

2020-06-10 06:06发布

问题:

How to use : HKUnit

Sample type Unit type Unit name Unit string Heart Rate count/time Beats per Minute "count/min”

回答1:

Swift : Heart Rate (bpm) save into healthkit store

 private func saveHeartRateIntoHealthStore(height:Double) -> Void
    {
        // Save the user's heart rate into HealthKit.
        let heartRateUnit: HKUnit = HKUnit.countUnit().unitDividedByUnit(HKUnit.minuteUnit())
        let heartRateQuantity: HKQuantity = HKQuantity(unit: heartRateUnit, doubleValue: height)

        var heartRate : HKQuantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)
        let nowDate: NSDate = NSDate()

        let heartRateSample: HKQuantitySample = HKQuantitySample(type: heartRate
            , quantity: heartRateQuantity, startDate: nowDate, endDate: nowDate)

        let completion: ((Bool, NSError!) -> Void) = {
            (success, error) -> Void in

            if !success {
                println("An error occured saving the Heart Rate sample \(heartRateSample). In your app, try to handle this gracefully. The error was: \(error).")

                abort()
            }

        }

        self.healthStore!.saveObject(heartRateSample, withCompletion: completion)

    }// end saveHeartRateIntoHealthStore


回答2:

In Swift 3:

func saveHeartRate(date: Date = Date(), heartRate heartRateValue: Double, completion completionBlock: @escaping (Bool, Error?) -> Void) {
    let unit = HKUnit.count().unitDivided(by: HKUnit.minute())
    let quantity = HKQuantity(unit: unit, doubleValue: heartRateValue)
    let type = HKQuantityType.quantityType(forIdentifier: .heartRate)!

    let heartRateSample = HKQuantitySample(type: type, quantity: quantity, start: date, end: date)

    self.healthKitStore.save(heartRateSample) { (success, error) -> Void in
        if !success {
            print("An error occured saving the HR sample \(heartRateSample). In your app, try to handle this gracefully. The error was: \(error).")
        }
        completionBlock(success, error)
    }
}


回答3:

In ObjectiveC (for those not using Swift, expanded for easy reading):

#define nilable __nullable
#define kCountPerMinUnitStr @"count/min"

typedef void (^VoidBoolErrorBlock) (BOOL        success,
                                    NSError *   nilable error);

enum {
    // Memory Constants
    kNil       = 0,
    kNilUPP    = 0,
    kNilRefCon = 0
};


/**
 writes a weight sample to HealthKit

 @param weight as HKQuantityTypeIdentifierBodyMass
 */
- (void) writeCDAHeartRateSample: ( NSStringPtr ) valueStr
                        cdaUnits: ( NSStringPtr ) cdaUnits
                            date: ( NSDate * ) date {      // was (CGFloat)
    double  theValue = kNil;

    // Each quantity consists of a value and a unit.
    HKUnit *            theMeasurementUnit = nil;
    HKQuantity *        theQuantity        = nil;

    HKQuantityType *    theHeartRateType   = nil;
    NSDate *            theDate            = nil;

    // For every sample, we need a sample type, quantity and a date.
    HKQuantitySample *  theSample = nil;
    VoidBoolErrorBlock  theBlock  = nil;

    theValue           = [ valueStr integerValue ];
//    theMeasurementUnit = [ HKUnit unitFromCDAString: cdaUnits ];
    theMeasurementUnit = [ HKUnit unitFromString: kCountPerMinUnitStr ];    /// FIXME: temp code StackOverflow example
    theQuantity        = [ HKQuantity quantityWithUnit: theMeasurementUnit
                                           doubleValue: theValue ];

    theHeartRateType = [ HKQuantityType quantityTypeForIdentifier: HKQuantityTypeIdentifierHeartRate ];
    theDate          = ( date != nil ) ? date : [ NSDate date ];///???: default to today's date?

    theBlock = [ self saveCDAHeartRateObjectBlock: theValue ];

    // For every sample, we need a sample type, quantity and a date.
    theSample = [HKQuantitySample quantitySampleWithType: theHeartRateType
                                                      quantity: theQuantity
                                                     startDate: theDate
                                                       endDate: theDate];
    [ self.healthStore saveObject: theSample
                   withCompletion: theBlock ];
}



/**
 companion block encapsulation for writeCDAHeartRateSample{}

 @return  completion block for saveObject: withCompletion in writeCDAHeartRateSample{}
 */
- ( VoidBoolErrorBlock ) saveCDAHeartRateObjectBlock: ( double ) value {
    VoidBoolErrorBlock theResult = nil;

    theResult = ^(BOOL success, NSError *error) {
        if (!success) {
            ///NSLog(@"Error while saving Heart Rate (%f) to Health Store: %@.", value, error);
        }
    };

    return theResult;
}