diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Activity.m b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Activity.m index eeb0d91d..378413ea 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Activity.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Activity.m @@ -35,8 +35,7 @@ - (void)activity_getActiveEnergyBurned:(NSDictionary *)input callback:(RCTRespon callback(@[[NSNull null], results]); return; } else { - NSLog(@"error getting active energy burned samples: %@", error); - callback(@[RCTMakeError(@"error getting active energy burned samples", nil, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } }]; @@ -65,8 +64,7 @@ - (void)activity_getBasalEnergyBurned:(NSDictionary *)input callback:(RCTRespons callback(@[[NSNull null], results]); return; } else { - NSLog(@"error getting basal energy burned samples: %@", error); - callback(@[RCTMakeError(@"error getting basal energy burned samples", nil, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } }]; diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Body.m b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Body.m index 34fd3288..3d1df24c 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Body.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Body.m @@ -24,8 +24,7 @@ - (void)body_getLatestWeight:(NSDictionary *)input callback:(RCTResponseSenderBl predicate:nil completion:^(HKQuantity *mostRecentQuantity, NSDate *startDate, NSDate *endDate, NSError *error) { if (!mostRecentQuantity) { - NSLog(@"error getting latest weight: %@", error); - callback(@[RCTMakeError(@"error getting latest weight", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); } else { // Determine the weight in the required unit. @@ -67,8 +66,7 @@ - (void)body_getWeightSamples:(NSDictionary *)input callback:(RCTResponseSenderB callback(@[[NSNull null], results]); return; } else { - NSLog(@"error getting weight samples: %@", error); - callback(@[RCTMakeError(@"error getting weight samples", nil, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } }]; @@ -87,8 +85,7 @@ - (void)body_saveWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)c [self.healthStore saveObject:weightSample withCompletion:^(BOOL success, NSError *error) { if (!success) { - NSLog(@"error saving the weight sample: %@", error); - callback(@[RCTMakeError(@"error saving the weight sample", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } callback(@[[NSNull null], @(weight)]); @@ -104,8 +101,7 @@ - (void)body_getLatestBodyMassIndex:(NSDictionary *)input callback:(RCTResponseS predicate:nil completion:^(HKQuantity *mostRecentQuantity, NSDate *startDate, NSDate *endDate, NSError *error) { if (!mostRecentQuantity) { - NSLog(@"error getting latest BMI: %@", error); - callback(@[RCTMakeError(@"error getting latest BMI", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); } else { // Determine the bmi in the required unit. @@ -136,8 +132,7 @@ - (void)body_saveBodyMassIndex:(NSDictionary *)input callback:(RCTResponseSender [self.healthStore saveObject:bmiSample withCompletion:^(BOOL success, NSError *error) { if (!success) { - NSLog(@"error saving BMI sample: %@.", error); - callback(@[RCTMakeError(@"error saving BMI sample", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } callback(@[[NSNull null], @(bmi)]); @@ -198,8 +193,7 @@ - (void)body_getHeightSamples:(NSDictionary *)input callback:(RCTResponseSenderB callback(@[[NSNull null], results]); return; } else { - NSLog(@"error getting height samples: %@", error); - callback(@[RCTMakeError(@"error getting height samples", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } }]; @@ -218,8 +212,7 @@ - (void)body_saveHeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)c [self.healthStore saveObject:heightSample withCompletion:^(BOOL success, NSError *error) { if (!success) { - NSLog(@"error saving height sample: %@", error); - callback(@[RCTMakeError(@"error saving height sample", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } callback(@[[NSNull null], @(height)]); @@ -235,8 +228,7 @@ - (void)body_getLatestBodyFatPercentage:(NSDictionary *)input callback:(RCTRespo predicate:nil completion:^(HKQuantity *mostRecentQuantity, NSDate *startDate, NSDate *endDate, NSError *error) { if (!mostRecentQuantity) { - NSLog(@"error getting latest body fat percentage: %@", error); - callback(@[RCTMakeError(@"error getting latest body fat percentage", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); } else { // Determine the weight in the required unit. @@ -265,8 +257,7 @@ - (void)body_getLatestLeanBodyMass:(NSDictionary *)input callback:(RCTResponseSe predicate:nil completion:^(HKQuantity *mostRecentQuantity, NSDate *startDate, NSDate *endDate, NSError *error) { if (!mostRecentQuantity) { - NSLog(@"error getting latest lean body mass: %@", error); - callback(@[RCTMakeError(@"error getting latest lean body mass", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); } else { HKUnit *weightUnit = [HKUnit poundUnit]; diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Characteristic.m b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Characteristic.m index e030b856..e6266a93 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Characteristic.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Characteristic.m @@ -34,8 +34,7 @@ - (void)characteristic_getBiologicalSex:(NSDictionary *)input callback:(RCTRespo } if(value == nil){ - NSLog(@"error getting biological sex: %@", error); - callback(@[RCTMakeError(@"error getting biological sex", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } @@ -52,8 +51,7 @@ - (void)characteristic_getDateOfBirth:(NSDictionary *)input callback:(RCTRespons NSDate *dob = [self.healthStore dateOfBirthWithError:&error]; if(error != nil){ - NSLog(@"error getting date of birth: %@", error); - callback(@[RCTMakeError(@"error getting date of birth", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } if(dob == nil) { diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.m b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.m index 9f0e5e24..eb812a17 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.m @@ -34,8 +34,7 @@ - (void)fitness_getStepCountOnDay:(NSDictionary *)input callback:(RCTResponseSen day:date completion:^(double value, NSDate *startDate, NSDate *endDate, NSError *error) { if (!value) { - NSLog(@"could not fetch step count for day: %@", error); - callback(@[RCTMakeError(@"could not fetch step count for day", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } @@ -118,8 +117,7 @@ - (void)fitness_getDailyStepSamples:(NSDictionary *)input callback:(RCTResponseS limit:limit completion:^(NSArray *arr, NSError *err){ if (err != nil) { - NSLog(@"error with fetchCumulativeSumStatisticsCollection: %@", err); - callback(@[RCTMakeError(@"error with fetchCumulativeSumStatisticsCollection", err, nil)]); + callback(@[RCTJSErrorFromNSError(err)]); return; } callback(@[[NSNull null], arr]); @@ -145,8 +143,7 @@ - (void)fitness_saveSteps:(NSDictionary *)input callback:(RCTResponseSenderBlock [self.healthStore saveObject:sample withCompletion:^(BOOL success, NSError *error) { if (!success) { - NSLog(@"An error occured saving the step count sample %@. The error was: %@.", sample, error); - callback(@[RCTMakeError(@"An error occured saving the step count sample", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } callback(@[[NSNull null], @(value)]); @@ -168,9 +165,7 @@ - (void)fitness_initializeStepEventObserver:(NSDictionary *)input callback:(RCTR NSError *error) { if (error) { - // Perform Proper Error Handling Here... - NSLog(@"*** An error occured while setting up the stepCount observer. %@ ***", error.localizedDescription); - callback(@[RCTMakeError(@"An error occured while setting up the stepCount observer", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } @@ -195,8 +190,7 @@ - (void)fitness_getDistanceWalkingRunningOnDay:(NSDictionary *)input callback:(R [self fetchSumOfSamplesOnDayForType:quantityType unit:unit day:date completion:^(double distance, NSDate *startDate, NSDate *endDate, NSError *error) { if (!distance) { - NSLog(@"ERROR getting DistanceWalkingRunning: %@", error); - callback(@[RCTMakeError(@"ERROR getting DistanceWalkingRunning", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } @@ -233,8 +227,7 @@ - (void)fitness_getDailyDistanceWalkingRunningSamples:(NSDictionary *)input call limit:limit completion:^(NSArray *arr, NSError *err){ if (err != nil) { - NSLog(@"error with fetchCumulativeSumStatisticsCollection: %@", err); - callback(@[RCTMakeError(@"error with fetchCumulativeSumStatisticsCollection", err, nil)]); + callback(@[RCTJSErrorFromNSError(err)]); return; } callback(@[[NSNull null], arr]); @@ -250,8 +243,7 @@ - (void)fitness_getDistanceCyclingOnDay:(NSDictionary *)input callback:(RCTRespo [self fetchSumOfSamplesOnDayForType:quantityType unit:unit day:date completion:^(double distance, NSDate *startDate, NSDate *endDate, NSError *error) { if (!distance) { - NSLog(@"ERROR getting DistanceCycling: %@", error); - callback(@[RCTMakeError(@"ERROR getting DistanceCycling", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } @@ -287,8 +279,7 @@ - (void)fitness_getDailyDistanceCyclingSamples:(NSDictionary *)input callback:(R limit:limit completion:^(NSArray *arr, NSError *err){ if (err != nil) { - NSLog(@"error with fetchCumulativeSumStatisticsCollection: %@", err); - callback(@[RCTMakeError(@"error with fetchCumulativeSumStatisticsCollection", err, nil)]); + callback(@[RCTJSErrorFromNSError(err)]); return; } callback(@[[NSNull null], arr]); @@ -304,8 +295,7 @@ - (void)fitness_getFlightsClimbedOnDay:(NSDictionary *)input callback:(RCTRespon [self fetchSumOfSamplesOnDayForType:quantityType unit:unit day:date completion:^(double count, NSDate *startDate, NSDate *endDate, NSError *error) { if (!count) { - NSLog(@"ERROR getting FlightsClimbed: %@", error); - callback(@[RCTMakeError(@"ERROR getting FlightsClimbed", error, nil), @(count)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } @@ -341,8 +331,7 @@ - (void)fitness_getDailyFlightsClimbedSamples:(NSDictionary *)input callback:(RC limit:limit completion:^(NSArray *arr, NSError *err){ if (err != nil) { - NSLog(@"error with fetchCumulativeSumStatisticsCollection: %@", err); - callback(@[RCTMakeError(@"error with fetchCumulativeSumStatisticsCollection", err, nil)]); + callback(@[RCTJSErrorFromNSError(err)]); return; } callback(@[[NSNull null], arr]); diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Mindfulness.m b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Mindfulness.m index b14ef813..1dc6dca9 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Mindfulness.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Mindfulness.m @@ -29,8 +29,7 @@ - (void)mindfulness_saveMindfulSession:(NSDictionary *)input callback:(RCTRespon [self.healthStore saveObject:sample withCompletion:^(BOOL success, NSError *error) { if (!success) { - NSLog(@"An error occured saving the mindful session sample %@. The error was: %@.", sample, error); - callback(@[RCTMakeError(@"An error occured saving the mindful session sample", error, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } callback(@[[NSNull null], @(value)]); diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Results.m b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Results.m index fd5d0345..a1c1cdea 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Results.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Results.m @@ -32,8 +32,7 @@ - (void)results_getBloodGlucoseSamples:(NSDictionary *)input callback:(RCTRespon callback(@[[NSNull null], results]); return; } else { - NSLog(@"error getting blood glucose samples: %@", error); - callback(@[RCTMakeError(@"error getting blood glucose samples", nil, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } }]; diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Sleep.m b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Sleep.m index faba4ed1..0894624e 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Sleep.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Sleep.m @@ -36,8 +36,7 @@ - (void)sleep_getSleepSamples:(NSDictionary *)input callback:(RCTResponseSenderB callback(@[[NSNull null], results]); return; } else { - NSLog(@"error getting sleep samples: %@", error); - callback(@[RCTMakeError(@"error getting sleep samples", nil, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } }]; diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Vitals.m b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Vitals.m index 74c53cb7..698a1b25 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Vitals.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Vitals.m @@ -33,8 +33,7 @@ - (void)vitals_getHeartRateSamples:(NSDictionary *)input callback:(RCTResponseSe callback(@[[NSNull null], results]); return; } else { - NSLog(@"error getting heart rate samples: %@", error); - callback(@[RCTMakeError(@"error getting heart rate samples", nil, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } }]; diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.h b/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.h index d69b7e95..c6668c69 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.h +++ b/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.h @@ -15,5 +15,7 @@ - (NSDictionary *)writePermsDict; - (NSSet *)getReadPermsFromOptions:(NSArray *)options; - (NSSet *)getWritePermsFromOptions:(NSArray *)options; +- (HKObjectType *)getWritePermFromString:(NSString *)string; +- (NSString *)getAuthorizationStatusString:(HKAuthorizationStatus)status; @end diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.m b/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.m index 6cb5a058..4925c3c7 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.m @@ -152,4 +152,18 @@ - (NSSet *)getWritePermsFromOptions:(NSArray *)options { return writePermSet; } +- (HKObjectType *)getWritePermFromString:(NSString *)writePerm { + return [[self writePermsDict] objectForKey:writePerm]; +} +- (NSString *)getAuthorizationStatusString:(HKAuthorizationStatus)status { + switch (status) { + case HKAuthorizationStatusNotDetermined: + return @"NotDetermined"; + case HKAuthorizationStatusSharingDenied: + return @"SharingDenied"; + case HKAuthorizationStatusSharingAuthorized: + return @"SharingAuthorized"; + } +} + @end diff --git a/RCTAppleHealthKit/RCTAppleHealthKit.m b/RCTAppleHealthKit/RCTAppleHealthKit.m index c91c4713..910fc9fa 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit.m @@ -266,9 +266,7 @@ - (void)initializeHealthKit:(NSDictionary *)input callback:(RCTResponseSenderBlo [self.healthStore requestAuthorizationToShareTypes:writeDataTypes readTypes:readDataTypes completion:^(BOOL success, NSError *error) { if (!success) { - NSString *errMsg = [NSString stringWithFormat:@"Error with HealthKit authorization: %@", error]; - NSLog(errMsg); - callback(@[RCTMakeError(errMsg, nil, nil)]); + callback(@[RCTJSErrorFromNSError(error)]); return; } else { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @@ -281,6 +279,28 @@ - (void)initializeHealthKit:(NSDictionary *)input callback:(RCTResponseSenderBlo } } +RCT_EXPORT_METHOD(authorizationStatusForType:(NSString *)type + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject +{ + if (self.healthStore == nil) { + self.healthStore = [[HKHealthStore alloc] init]; + } + + if ([HKHealthStore isHealthDataAvailable]) { + HKObjectType *objectType = [self getWritePermFromString:type]; + if (objectType == nil) { + reject(@"unknown write permission", nil, nil); + return; + } + + NSString *status = [self getAuthorizationStatusString:[self.healthStore authorizationStatusForType:objectType]]; + resolve(status); + } else { + reject(@"HealthKit data is not available", nil, nil); + } +}) + - (void)getModuleInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback { NSDictionary *info = @{ diff --git a/README.md b/README.md index b5e2e20f..b3ee3c34 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ AppleHealthKit.initHealthKit(options: Object, (err: string, results: Object) => * Base Methods * [isAvailable](/docs/isAvailable().md) * [initHealthKit](/docs/initHealthKit().md) + * [authorizationStatusForType](/docs/authorizationStatusForType().md) * Realtime Methods * [initStepCountObserver](/docs/initStepCountObserver().md) * [setObserver](/docs/setObserver().md) diff --git a/docs/authorizationStatusForType().md b/docs/authorizationStatusForType().md new file mode 100644 index 00000000..8687b89b --- /dev/null +++ b/docs/authorizationStatusForType().md @@ -0,0 +1,16 @@ +Check the authorization status for sharing (writing) the specified data type. + +Status will be one of `"NotDetermined"`, `"SharingDenied"`, `"SharingAuthorized"`. + +```javascript +try { +const status = await AppleHealthKit.authorizationStatusForType("StepCount") +if (status) { + console.log("status is", status) +} +} catch (error) { + console.warn(error) +} +``` + +There is no way to check authorization status for read permission, [see this](https://developer.apple.com/documentation/healthkit/hkhealthstore/1614154-authorizationstatusfortype?language=objc).