Commit a8099f45 authored by Greg Wilson's avatar Greg Wilson

Merge branch 'master' of github.com-GregWilson:GregWilson/react-native-apple-healthkit

parents 38684319 15d35dc4
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
3774C8D41D20C6390000B3F3 /* RCTAppleHealthKit+Methods_Body.m in Sources */ = {isa = PBXBuildFile; fileRef = 3774C8D31D20C6390000B3F3 /* RCTAppleHealthKit+Methods_Body.m */; }; 3774C8D41D20C6390000B3F3 /* RCTAppleHealthKit+Methods_Body.m in Sources */ = {isa = PBXBuildFile; fileRef = 3774C8D31D20C6390000B3F3 /* RCTAppleHealthKit+Methods_Body.m */; };
3774C8D71D20C65F0000B3F3 /* RCTAppleHealthKit+Methods_Fitness.m in Sources */ = {isa = PBXBuildFile; fileRef = 3774C8D61D20C65F0000B3F3 /* RCTAppleHealthKit+Methods_Fitness.m */; }; 3774C8D71D20C65F0000B3F3 /* RCTAppleHealthKit+Methods_Fitness.m in Sources */ = {isa = PBXBuildFile; fileRef = 3774C8D61D20C65F0000B3F3 /* RCTAppleHealthKit+Methods_Fitness.m */; };
377D44F31D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.m in Sources */ = {isa = PBXBuildFile; fileRef = 377D44F21D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.m */; }; 377D44F31D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.m in Sources */ = {isa = PBXBuildFile; fileRef = 377D44F21D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.m */; };
64C42D4A1D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.m in Sources */ = {isa = PBXBuildFile; fileRef = 64C42D491D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.m */; };
64E0E73F1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.m in Sources */ = {isa = PBXBuildFile; fileRef = 64E0E73E1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.m */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
...@@ -46,6 +48,10 @@ ...@@ -46,6 +48,10 @@
3774C8D61D20C65F0000B3F3 /* RCTAppleHealthKit+Methods_Fitness.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+Methods_Fitness.m"; sourceTree = "<group>"; }; 3774C8D61D20C65F0000B3F3 /* RCTAppleHealthKit+Methods_Fitness.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+Methods_Fitness.m"; sourceTree = "<group>"; };
377D44F11D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTAppleHealthKit+Methods_Characteristic.h"; sourceTree = "<group>"; }; 377D44F11D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTAppleHealthKit+Methods_Characteristic.h"; sourceTree = "<group>"; };
377D44F21D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+Methods_Characteristic.m"; sourceTree = "<group>"; }; 377D44F21D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+Methods_Characteristic.m"; sourceTree = "<group>"; };
64C42D481D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTAppleHealthKit+Methods_Vitals.h"; sourceTree = "<group>"; };
64C42D491D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+Methods_Vitals.m"; sourceTree = "<group>"; };
64E0E73D1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTAppleHealthKit+Methods_Results.h"; sourceTree = "<group>"; };
64E0E73E1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTAppleHealthKit+Methods_Results.m"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
...@@ -78,6 +84,10 @@ ...@@ -78,6 +84,10 @@
3774C88F1D2092F20000B3F3 /* RCTAppleHealthKit */ = { 3774C88F1D2092F20000B3F3 /* RCTAppleHealthKit */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
64E0E73D1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.h */,
64E0E73E1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.m */,
64C42D481D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.h */,
64C42D491D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.m */,
3774C8901D2092F20000B3F3 /* RCTAppleHealthKit.h */, 3774C8901D2092F20000B3F3 /* RCTAppleHealthKit.h */,
3774C8921D2092F20000B3F3 /* RCTAppleHealthKit.m */, 3774C8921D2092F20000B3F3 /* RCTAppleHealthKit.m */,
3774C8991D2095450000B3F3 /* RCTAppleHealthKit+Queries.h */, 3774C8991D2095450000B3F3 /* RCTAppleHealthKit+Queries.h */,
...@@ -155,6 +165,8 @@ ...@@ -155,6 +165,8 @@
3774C89B1D2095450000B3F3 /* RCTAppleHealthKit+Queries.m in Sources */, 3774C89B1D2095450000B3F3 /* RCTAppleHealthKit+Queries.m in Sources */,
3774C8A11D20A6B90000B3F3 /* RCTAppleHealthKit+Utils.m in Sources */, 3774C8A11D20A6B90000B3F3 /* RCTAppleHealthKit+Utils.m in Sources */,
3774C8D41D20C6390000B3F3 /* RCTAppleHealthKit+Methods_Body.m in Sources */, 3774C8D41D20C6390000B3F3 /* RCTAppleHealthKit+Methods_Body.m in Sources */,
64E0E73F1D37947B00EAB905 /* RCTAppleHealthKit+Methods_Results.m in Sources */,
64C42D4A1D351A8800A0A8F7 /* RCTAppleHealthKit+Methods_Vitals.m in Sources */,
3774C8931D2092F20000B3F3 /* RCTAppleHealthKit.m in Sources */, 3774C8931D2092F20000B3F3 /* RCTAppleHealthKit.m in Sources */,
377D44F31D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.m in Sources */, 377D44F31D247D0A004E35CB /* RCTAppleHealthKit+Methods_Characteristic.m in Sources */,
3774C89E1D2095850000B3F3 /* RCTAppleHealthKit+TypesAndPermissions.m in Sources */, 3774C89E1D2095850000B3F3 /* RCTAppleHealthKit+TypesAndPermissions.m in Sources */,
......
#import "RCTAppleHealthKit.h"
@interface RCTAppleHealthKit (Methods_Results)
- (void)results_getBloodGlucoseSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
@end
#import "RCTAppleHealthKit+Methods_Results.h"
#import "RCTAppleHealthKit+Queries.h"
#import "RCTAppleHealthKit+Utils.h"
@implementation RCTAppleHealthKit (Methods_Results)
- (void)results_getBloodGlucoseSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKQuantityType *bloodGlucoseType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodGlucose];
HKUnit *mmoLPerL = [[HKUnit moleUnitWithMetricPrefix:HKMetricPrefixMilli molarMass:HKUnitMolarMassBloodGlucose] unitDividedByUnit:[HKUnit literUnit]];
HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:mmoLPerL];
NSUInteger limit = [RCTAppleHealthKit uintFromOptions:input key:@"limit" withDefault:HKObjectQueryNoLimit];
BOOL ascending = [RCTAppleHealthKit boolFromOptions:input key:@"ascending" withDefault:false];
NSDate *startDate = [RCTAppleHealthKit dateFromOptions:input key:@"startDate" withDefault:nil];
NSDate *endDate = [RCTAppleHealthKit dateFromOptions:input key:@"endDate" withDefault:[NSDate date]];
if(startDate == nil){
callback(@[RCTMakeError(@"startDate is required in options", nil, nil)]);
return;
}
NSPredicate * predicate = [RCTAppleHealthKit predicateForSamplesBetweenDates:startDate endDate:endDate];
[self fetchQuantitySamplesOfType:bloodGlucoseType
unit:unit
predicate:predicate
ascending:ascending
limit:limit
completion:^(NSArray *results, NSError *error) {
if(results){
callback(@[[NSNull null], results]);
return;
} else {
NSLog(@"error getting blood glucose samples: %@", error);
callback(@[RCTMakeError(@"error getting blood glucose samples", nil, nil)]);
return;
}
}];
}
@end
#import "RCTAppleHealthKit.h"
@interface RCTAppleHealthKit (Methods_Vitals)
- (void)vitals_getHeartRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
- (void)vitals_getBodyTemperatureSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
- (void)vitals_getBloodPressureSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
- (void)vitals_getRespiratoryRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
@end
#import "RCTAppleHealthKit+Methods_Vitals.h"
#import "RCTAppleHealthKit+Queries.h"
#import "RCTAppleHealthKit+Utils.h"
@implementation RCTAppleHealthKit (Methods_Vitals)
- (void)vitals_getHeartRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKQuantityType *heartRateType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate];
HKUnit *count = [HKUnit countUnit];
HKUnit *minute = [HKUnit minuteUnit];
HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[count unitDividedByUnit:minute]];
NSUInteger limit = [RCTAppleHealthKit uintFromOptions:input key:@"limit" withDefault:HKObjectQueryNoLimit];
BOOL ascending = [RCTAppleHealthKit boolFromOptions:input key:@"ascending" withDefault:false];
NSDate *startDate = [RCTAppleHealthKit dateFromOptions:input key:@"startDate" withDefault:nil];
NSDate *endDate = [RCTAppleHealthKit dateFromOptions:input key:@"endDate" withDefault:[NSDate date]];
if(startDate == nil){
callback(@[RCTMakeError(@"startDate is required in options", nil, nil)]);
return;
}
NSPredicate * predicate = [RCTAppleHealthKit predicateForSamplesBetweenDates:startDate endDate:endDate];
[self fetchQuantitySamplesOfType:heartRateType
unit:unit
predicate:predicate
ascending:ascending
limit:limit
completion:^(NSArray *results, NSError *error) {
if(results){
callback(@[[NSNull null], results]);
return;
} else {
NSLog(@"error getting heart rate samples: %@", error);
callback(@[RCTMakeError(@"error getting heart rate samples", nil, nil)]);
return;
}
}];
}
- (void)vitals_getBodyTemperatureSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKQuantityType *bodyTemperatureType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyTemperature];
HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[HKUnit degreeCelsiusUnit]];
NSUInteger limit = [RCTAppleHealthKit uintFromOptions:input key:@"limit" withDefault:HKObjectQueryNoLimit];
BOOL ascending = [RCTAppleHealthKit boolFromOptions:input key:@"ascending" withDefault:false];
NSDate *startDate = [RCTAppleHealthKit dateFromOptions:input key:@"startDate" withDefault:nil];
NSDate *endDate = [RCTAppleHealthKit dateFromOptions:input key:@"endDate" withDefault:[NSDate date]];
if(startDate == nil){
callback(@[RCTMakeError(@"startDate is required in options", nil, nil)]);
return;
}
NSPredicate * predicate = [RCTAppleHealthKit predicateForSamplesBetweenDates:startDate endDate:endDate];
[self fetchQuantitySamplesOfType:bodyTemperatureType
unit:unit
predicate:predicate
ascending:ascending
limit:limit
completion:^(NSArray *results, NSError *error) {
if(results){
callback(@[[NSNull null], results]);
return;
} else {
NSLog(@"error getting body temperature samples: %@", error);
callback(@[RCTMakeError(@"error getting body temperature samples", nil, nil)]);
return;
}
}];
}
- (void)vitals_getBloodPressureSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKCorrelationType *bloodPressureCorrelationType = [HKCorrelationType correlationTypeForIdentifier:HKCorrelationTypeIdentifierBloodPressure];
HKQuantityType *systolicType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodPressureSystolic];
HKQuantityType *diastolicType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodPressureDiastolic];
HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[HKUnit millimeterOfMercuryUnit]];
NSUInteger limit = [RCTAppleHealthKit uintFromOptions:input key:@"limit" withDefault:HKObjectQueryNoLimit];
BOOL ascending = [RCTAppleHealthKit boolFromOptions:input key:@"ascending" withDefault:false];
NSDate *startDate = [RCTAppleHealthKit dateFromOptions:input key:@"startDate" withDefault:nil];
NSDate *endDate = [RCTAppleHealthKit dateFromOptions:input key:@"endDate" withDefault:[NSDate date]];
if(startDate == nil){
callback(@[RCTMakeError(@"startDate is required in options", nil, nil)]);
return;
}
NSPredicate * predicate = [RCTAppleHealthKit predicateForSamplesBetweenDates:startDate endDate:endDate];
[self fetchCorrelationSamplesOfType:bloodPressureCorrelationType
unit:unit
predicate:predicate
ascending:ascending
limit:limit
completion:^(NSArray *results, NSError *error) {
if(results){
NSMutableArray *data = [NSMutableArray arrayWithCapacity:1];
for (NSDictionary *sample in results) {
HKCorrelation *bloodPressureValues = [sample valueForKey:@"correlation"];
HKQuantitySample *bloodPressureSystolicValue = [bloodPressureValues objectsForType:systolicType].anyObject;
HKQuantitySample *bloodPressureDiastolicValue = [bloodPressureValues objectsForType:diastolicType].anyObject;
NSDictionary *elem = @{
@"bloodPressureSystolicValue" : @([bloodPressureSystolicValue.quantity doubleValueForUnit:unit]),
@"bloodPressureDiastolicValue" : @([bloodPressureDiastolicValue.quantity doubleValueForUnit:unit]),
@"startDate" : [sample valueForKey:@"startDate"],
@"endDate" : [sample valueForKey:@"endDate"],
};
[data addObject:elem];
}
callback(@[[NSNull null], data]);
return;
} else {
NSLog(@"error getting blood pressure samples: %@", error);
callback(@[RCTMakeError(@"error getting blood pressure samples", nil, nil)]);
return;
}
}];
}
- (void)vitals_getRespiratoryRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKQuantityType *respiratoryRateType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierRespiratoryRate];
HKUnit *count = [HKUnit countUnit];
HKUnit *minute = [HKUnit minuteUnit];
HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[count unitDividedByUnit:minute]];
NSUInteger limit = [RCTAppleHealthKit uintFromOptions:input key:@"limit" withDefault:HKObjectQueryNoLimit];
BOOL ascending = [RCTAppleHealthKit boolFromOptions:input key:@"ascending" withDefault:false];
NSDate *startDate = [RCTAppleHealthKit dateFromOptions:input key:@"startDate" withDefault:nil];
NSDate *endDate = [RCTAppleHealthKit dateFromOptions:input key:@"endDate" withDefault:[NSDate date]];
if(startDate == nil){
callback(@[RCTMakeError(@"startDate is required in options", nil, nil)]);
return;
}
NSPredicate * predicate = [RCTAppleHealthKit predicateForSamplesBetweenDates:startDate endDate:endDate];
[self fetchQuantitySamplesOfType:respiratoryRateType
unit:unit
predicate:predicate
ascending:ascending
limit:limit
completion:^(NSArray *results, NSError *error) {
if(results){
callback(@[[NSNull null], results]);
return;
} else {
NSLog(@"error getting respiratory rate samples: %@", error);
callback(@[RCTMakeError(@"error getting respiratory rate samples", nil, nil)]);
return;
}
}];
}
@end
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
completion:(void (^)(NSArray *, NSError *))completionHandler; completion:(void (^)(NSArray *, NSError *))completionHandler;
- (void)fetchQuantitySamplesOfType:(HKQuantityType *)quantityType - (void)fetchQuantitySamplesOfType:(HKQuantityType *)quantityType
unit:(HKUnit *)unit unit:(HKUnit *)unit
predicate:(NSPredicate *)predicate predicate:(NSPredicate *)predicate
...@@ -30,6 +29,12 @@ ...@@ -30,6 +29,12 @@
completion:(void (^)(NSArray *, NSError *))completion; completion:(void (^)(NSArray *, NSError *))completion;
- (void)fetchCorrelationSamplesOfType:(HKQuantityType *)quantityType
unit:(HKUnit *)unit
predicate:(NSPredicate *)predicate
ascending:(BOOL)asc
limit:(NSUInteger)lim
completion:(void (^)(NSArray *, NSError *))completion;
- (void)fetchCumulativeSumStatisticsCollection:(HKQuantityType *)quantityType - (void)fetchCumulativeSumStatisticsCollection:(HKQuantityType *)quantityType
......
...@@ -108,7 +108,60 @@ ...@@ -108,7 +108,60 @@
} }
- (void)fetchCorrelationSamplesOfType:(HKQuantityType *)quantityType
unit:(HKUnit *)unit
predicate:(NSPredicate *)predicate
ascending:(BOOL)asc
limit:(NSUInteger)lim
completion:(void (^)(NSArray *, NSError *))completion {
NSSortDescriptor *timeSortDescriptor = [[NSSortDescriptor alloc] initWithKey:HKSampleSortIdentifierEndDate
ascending:asc];
// declare the block
void (^handlerBlock)(HKSampleQuery *query, NSArray *results, NSError *error);
// create and assign the block
handlerBlock = ^(HKSampleQuery *query, NSArray *results, NSError *error) {
if (!results) {
if (completion) {
completion(nil, error);
}
return;
}
if (completion) {
NSMutableArray *data = [NSMutableArray arrayWithCapacity:1];
dispatch_async(dispatch_get_main_queue(), ^{
for (HKCorrelation *sample in results) {
NSString *startDateString = [RCTAppleHealthKit buildISO8601StringFromDate:sample.startDate];
NSString *endDateString = [RCTAppleHealthKit buildISO8601StringFromDate:sample.endDate];
NSDictionary *elem = @{
@"correlation" : sample,
@"startDate" : startDateString,
@"endDate" : endDateString,
};
[data addObject:elem];
}
completion(data, error);
});
}
};
HKSampleQuery *query = [[HKSampleQuery alloc] initWithSampleType:quantityType
predicate:predicate
limit:lim
sortDescriptors:@[timeSortDescriptor]
resultsHandler:handlerBlock];
[self.healthStore executeQuery:query];
}
......
...@@ -36,6 +36,14 @@ ...@@ -36,6 +36,14 @@
@"AppleExerciseTime" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierAppleExerciseTime], @"AppleExerciseTime" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierAppleExerciseTime],
// Nutrition Identifiers // Nutrition Identifiers
@"DietaryEnergy" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryEnergyConsumed], @"DietaryEnergy" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDietaryEnergyConsumed],
// Vital Signs Identifiers
@"HeartRate" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate],
@"BodyTemperature" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyTemperature],
@"BloodPressureSystolic" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodPressureSystolic],
@"BloodPressureDiastolic" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodPressureDiastolic],
@"RespiratoryRate" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierRespiratoryRate],
// Results Identifiers
@"BloodGlucose" : [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodGlucose],
}; };
return readPerms; return readPerms;
} }
......
...@@ -225,6 +225,27 @@ ...@@ -225,6 +225,27 @@
if([unitString isEqualToString:@"percent"]){ if([unitString isEqualToString:@"percent"]){
theUnit = [HKUnit percentUnit]; theUnit = [HKUnit percentUnit];
} }
if([unitString isEqualToString:@"bpm"]){
HKUnit *count = [HKUnit countUnit];
HKUnit *minute = [HKUnit minuteUnit];
theUnit = [count unitDividedByUnit:minute];
}
if([unitString isEqualToString:@"fahrenheit"]){
theUnit = [HKUnit degreeFahrenheitUnit];
}
if([unitString isEqualToString:@"celsius"]){
theUnit = [HKUnit degreeCelsiusUnit];
}
if([unitString isEqualToString:@"mmhg"]){
theUnit = [HKUnit millimeterOfMercuryUnit];
}
if([unitString isEqualToString:@"mmolPerL"]){
theUnit = [[HKUnit moleUnitWithMetricPrefix:HKMetricPrefixMilli molarMass:HKUnitMolarMassBloodGlucose] unitDividedByUnit:[HKUnit literUnit]];
}
if([unitString isEqualToString:@"mgPerdL"]){
theUnit = [HKUnit unitFromString:@"mg/dL"];
}
if(theUnit == nil){ if(theUnit == nil){
theUnit = defaultValue; theUnit = defaultValue;
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#import "RCTAppleHealthKit+Methods_Body.h" #import "RCTAppleHealthKit+Methods_Body.h"
#import "RCTAppleHealthKit+Methods_Fitness.h" #import "RCTAppleHealthKit+Methods_Fitness.h"
#import "RCTAppleHealthKit+Methods_Characteristic.h" #import "RCTAppleHealthKit+Methods_Characteristic.h"
#import "RCTAppleHealthKit+Methods_Vitals.h"
#import "RCTAppleHealthKit+Methods_Results.h"
@implementation RCTAppleHealthKit @implementation RCTAppleHealthKit
...@@ -134,6 +136,30 @@ RCT_EXPORT_METHOD(getFlightsClimbed:(NSDictionary *)input callback:(RCTResponseS ...@@ -134,6 +136,30 @@ RCT_EXPORT_METHOD(getFlightsClimbed:(NSDictionary *)input callback:(RCTResponseS
[self fitness_getFlightsClimbedOnDay:input callback:callback]; [self fitness_getFlightsClimbedOnDay:input callback:callback];
} }
RCT_EXPORT_METHOD(getHeartRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self vitals_getHeartRateSamples:input callback:callback];
}
RCT_EXPORT_METHOD(getBodyTemperatureSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self vitals_getBodyTemperatureSamples:input callback:callback];
}
RCT_EXPORT_METHOD(getBloodPressureSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self vitals_getBloodPressureSamples:input callback:callback];
}
RCT_EXPORT_METHOD(getRespiratoryRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self vitals_getRespiratoryRateSamples:input callback:callback];
}
RCT_EXPORT_METHOD(getBloodGlucoseSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self results_getBloodGlucoseSamples:input callback:callback];
}
RCT_EXPORT_METHOD(getInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) RCT_EXPORT_METHOD(getInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
......
...@@ -38,6 +38,11 @@ A React Native bridge module for interacting with [Apple HealthKit] data. ...@@ -38,6 +38,11 @@ A React Native bridge module for interacting with [Apple HealthKit] data.
* [saveBmi](#savebmi) * [saveBmi](#savebmi)
* [getLatestBodyFatPercentage](#getlatestbodyfatpercentage) * [getLatestBodyFatPercentage](#getlatestbodyfatpercentage)
* [getLatestLeanBodyMass](#getlatestleanbodymass) * [getLatestLeanBodyMass](#getlatestleanbodymass)
* [getHeartRateSamples](#getheartratesamples)
* [getBodyTemperatureSamples](#getbodytemperaturesamples)
* [getBloodPressureSamples](#getbloodpressuresamples)
* [getRespiratoryRateSamples](#getrespiratoryratesamples)
* [getBloodGlucoseSamples](#getbloodglucosesamples)
* [Examples](#examples) * [Examples](#examples)
...@@ -143,6 +148,13 @@ The available HealthKit permissions to use with `initHealthKit` ...@@ -143,6 +148,13 @@ The available HealthKit permissions to use with `initHealthKit`
| NikeFuel | [HKQuantityTypeIdentifierNikeFuel](https://developer.apple.com/reference/healthkit/hkquantitytypeidentifiernikefuel?language=objc) | ✓ | | | NikeFuel | [HKQuantityTypeIdentifierNikeFuel](https://developer.apple.com/reference/healthkit/hkquantitytypeidentifiernikefuel?language=objc) | ✓ | |
| AppleExerciseTime | [HKQuantityTypeIdentifierAppleExerciseTime](https://developer.apple.com/reference/healthkit/hkquantitytypeidentifierappleexercisetime?language=objc) | ✓ | | | AppleExerciseTime | [HKQuantityTypeIdentifierAppleExerciseTime](https://developer.apple.com/reference/healthkit/hkquantitytypeidentifierappleexercisetime?language=objc) | ✓ | |
| DietaryEnergy | [HKQuantityTypeIdentifierDietaryEnergyConsumed](https://developer.apple.com/reference/healthkit/hkquantitytypeidentifierdietaryenergyconsumed?language=objc) | ✓ | ✓ | | DietaryEnergy | [HKQuantityTypeIdentifierDietaryEnergyConsumed](https://developer.apple.com/reference/healthkit/hkquantitytypeidentifierdietaryenergyconsumed?language=objc) | ✓ | ✓ |
| HeartRate | [HKQuantityTypeIdentifierHeartRate](https://developer.apple.com/reference/healthkit/hkquantitytypeidentifierheartrate?language=objc) | ✓ | |
| BodyTemperature | [HKQuantityTypeIdentifierBodyTemperature](https://developer.apple.com/reference/healthkit/hkquantitytypeidentifierbodytemperature?language=objc) | ✓ | |
| BloodPressureSystolic | [HKQuantityTypeIdentifierBloodPressureSystolic](https://developer.apple.com/reference/healthkit/hkquantitytypeidentifierbloodpressuresystolic?language=objc) | ✓ | |
| BloodPressureDiastolic | [HKQuantityTypeIdentifierBloodPressureDiastolic](https://developer.apple.com/reference/healthkit/hkquantitytypeidentifierbloodpressurediastolic?language=objc) | ✓ | |
| RespiratoryRate | [HKQuantityTypeIdentifierRespiratoryRate](https://developer.apple.com/reference/healthkit/hkquantitytypeidentifierrespiratoryrate?language=objc) | ✓ | |
| BloodGlucose | [HKQuantityTypeIdentifierBloodGlucose](https://developer.apple.com/reference/healthkit/hkquantitytypeidentifierbloodglucose?language=objc) | ✓ | |
These permissions are exported as constants of the `react-native-apple-healthkit` module. These permissions are exported as constants of the `react-native-apple-healthkit` module.
...@@ -715,6 +727,148 @@ On success, the callback function will be provided with a `leanBodyMass` object ...@@ -715,6 +727,148 @@ On success, the callback function will be provided with a `leanBodyMass` object
}); });
``` ```
___
#### **`getHeartRateSamples`**
query for heart rate samples. the options object is used to setup a query to retrieve relevant samples.
```javascript
let options = {
unit: 'bpm', // optional; default 'bpm'
startDate: (new Date(2016,4,27)).toISOString(), // required
endDate: (new Date()).toISOString(), // optional; default now
ascending: false, // optional; default false
limit:10, // optional; default no limit
};
```
the callback function will be called with a `samples` array containing objects with *value*, *startDate*, and *endDate* fields
*example usage*
```javascript
AppleHealthKit.getHeartRateSamples(options, (err: Object, samples: Array<Object>) => {
if(this._handleHealthKitError(err, 'getHeartRateSamples')){
return;
}
// use samples ...
});
```
___
#### **`getBodyTemperatureSamples`**
query for body temperature samples. the options object is used to setup a query to retrieve relevant samples.
```javascript
let options = {
unit: 'celsius', // optional; default 'celsius'
startDate: (new Date(2016,4,27)).toISOString(), // required
endDate: (new Date()).toISOString(), // optional; default now
ascending: false, // optional; default false
limit:10, // optional; default no limit
};
```
available units are: `'fahrenheit'`, `'celsius'`.
the callback function will be called with a `samples` array containing objects with *value*, *startDate*, and *endDate* fields.
*example usage*
```javascript
AppleHealthKit.getBodyTemperatureSamples(options, (err: Object, samples: Array<Object>) => {
if(this._handleHealthKitError(err, 'getBodyTemperatureSamples')){
return;
}
// use samples ...
});
```
___
#### **`getBloodPressureSamples`**
query for blood pressure samples. the options object is used to setup a query to retrieve relevant samples.
```javascript
let options = {
unit: 'mmhg', // optional; default 'mmhg'
startDate: (new Date(2016,4,27)).toISOString(), // required
endDate: (new Date()).toISOString(), // optional; default now
ascending: false, // optional; default false
limit:10, // optional; default no limit
};
```
the callback function will be called with a `samples` array containing objects with *bloodPressureSystolicValue*, *bloodPressureDiastolicValue*, *startDate*, and *endDate* fields
```javascript
// samples is array of objects
[
{bloodPressureSystolicValue: 120, bloodPressureDiastolicValue: 81, startDate:'2016-06-29T17:55:00.000-0400', endDate:'2016-06-29T17:55:00.000-0400'},
{bloodPressureSystolicValue: 119, bloodPressureDiastolicValue: 77, startDate:'2016-03-12T13:22:00.000-0400', endDate:'2016-03-12T13:22:00.000-0400'},
...
]
```
*example usage*
```javascript
AppleHealthKit.getBloodPressureSamples(options, (err: Object, samples: Array<Object>) => {
if(this._handleHealthKitError(err, 'getBloodPressureSamples')){
return;
}
// use samples ...
});
```
___
#### **`getRespiratoryRateSamples`**
query for respiratory rate samples. the options object is used to setup a query to retrieve relevant samples.
```javascript
let options = {
unit: 'bpm', // optional; default 'bpm'
startDate: (new Date(2016,4,27)).toISOString(), // required
endDate: (new Date()).toISOString(), // optional; default now
ascending: false, // optional; default false
limit:10, // optional; default no limit
};
```
the callback function will be called with a `samples` array containing objects with *value*, *startDate*, and *endDate* fields
*example usage*
```javascript
AppleHealthKit.getRespiratoryRateSamples(options, (err: Object, samples: Array<Object>) => {
if(this._handleHealthKitError(err, 'getRespiratoryRateSamples')){
return;
}
// use samples ...
});
```
___
#### **`getBloodGlucoseSamples`**
query for blood glucose samples. the options object is used to setup a query to retrieve relevant samples.
```javascript
let options = {
unit: 'mmolPerL', // optional; default 'mmolPerL'
startDate: (new Date(2016,4,27)).toISOString(), // required
endDate: (new Date()).toISOString(), // optional; default now
ascending: false, // optional; default false
limit:10, // optional; default no limit
};
```
available units are: `'mmolPerL'`, `'mgPerdL'`.
the callback function will be called with a `samples` array containing objects with *value*, *startDate*, and *endDate* fields
*example usage*
```javascript
AppleHealthKit.getBloodGlucoseSamples(options, (err: Object, samples: Array<Object>) => {
if(this._handleHealthKitError(err, 'getBloodGlucoseSamples')){
return;
}
// use samples ...
});
```
## Examples ## Examples
#### StepsDemo #### StepsDemo
......
...@@ -19,6 +19,12 @@ const PERMISSIONS = { ...@@ -19,6 +19,12 @@ const PERMISSIONS = {
NikeFuel: 'NikeFuel', NikeFuel: 'NikeFuel',
AppleExerciseTime: 'AppleExerciseTime', AppleExerciseTime: 'AppleExerciseTime',
DietaryEnergy: 'DietaryEnergy', DietaryEnergy: 'DietaryEnergy',
HeartRate: 'HeartRate',
BodyTemperature: 'BodyTemperature',
BloodPressureSystolic: 'BloodPressureSystolic',
BloodPressureDiastolic: 'BloodPressureDiastolic',
RespiratoryRate: 'RespiratoryRate',
BloodGlucose: 'BloodGlucose',
}; };
...@@ -36,7 +42,13 @@ const UNITS = { ...@@ -36,7 +42,13 @@ const UNITS = {
joule: 'joule', joule: 'joule',
calorie: 'calorie', calorie: 'calorie',
count: 'count', count: 'count',
percent: 'percent' percent: 'percent',
bpm: 'bpm',
fahrenheit: 'fahrenheit',
celsius: 'celsius',
mmhg: 'mmhg',
mmolPerL: 'mmolPerL',
mgPerdL: 'mgPerdL',
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment