How to use : HKUnit
Sample type Unit type Unit name Unit string Heart Rate count/time Beats per Minute \"count/min”
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;
}
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
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)
}
}