// // RCTAppleHealthKit.m // RCTAppleHealthKit // // Created by Greg Wilson on 2016-06-26. // Copyright © 2016 Greg Wilson. All rights reserved. // #import "RCTAppleHealthKit.h" #import "RCTAppleHealthKit+TypesAndPermissions.h" #import "RCTAppleHealthKit+Methods_Activity.h" #import "RCTAppleHealthKit+Methods_Body.h" #import "RCTAppleHealthKit+Methods_Fitness.h" #import "RCTAppleHealthKit+Methods_Dietary.h" #import "RCTAppleHealthKit+Methods_Characteristic.h" #import "RCTAppleHealthKit+Methods_Vitals.h" #import "RCTAppleHealthKit+Methods_Results.h" #import "RCTAppleHealthKit+Methods_Sleep.h" #import "RCTAppleHealthKit+Methods_Mindfulness.h" #import #import @implementation RCTAppleHealthKit @synthesize bridge = _bridge; RCT_EXPORT_MODULE(); RCT_EXPORT_METHOD(isAvailable:(RCTResponseSenderBlock)callback) { [self isHealthKitAvailable:callback]; } RCT_EXPORT_METHOD(initHealthKit:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self initializeHealthKit:input callback:callback]; } RCT_EXPORT_METHOD(initStepCountObserver:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self fitness_initializeStepEventObserver:input callback:callback]; } RCT_EXPORT_METHOD(getBiologicalSex:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self characteristic_getBiologicalSex:input callback:callback]; } RCT_EXPORT_METHOD(getDateOfBirth:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self characteristic_getDateOfBirth:input callback:callback]; } RCT_EXPORT_METHOD(getLatestWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self body_getLatestWeight:input callback:callback]; } RCT_EXPORT_METHOD(getWeightSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self body_getWeightSamples:input callback:callback]; } RCT_EXPORT_METHOD(saveWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self body_saveWeight:input callback:callback]; } RCT_EXPORT_METHOD(getLatestHeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self body_getLatestHeight:input callback:callback]; } RCT_EXPORT_METHOD(getHeightSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self body_getHeightSamples:input callback:callback]; } RCT_EXPORT_METHOD(saveHeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self body_saveHeight:input callback:callback]; } RCT_EXPORT_METHOD(getLatestBmi:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self body_getLatestBodyMassIndex:input callback:callback]; } RCT_EXPORT_METHOD(saveBmi:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self body_saveBodyMassIndex:input callback:callback]; } RCT_EXPORT_METHOD(getLatestBodyFatPercentage:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self body_getLatestBodyFatPercentage:input callback:callback]; } RCT_EXPORT_METHOD(getLatestLeanBodyMass:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self body_getLatestLeanBodyMass:input callback:callback]; } RCT_EXPORT_METHOD(getStepCount:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self fitness_getStepCountOnDay:input callback:callback]; } RCT_EXPORT_METHOD(getDailyStepCountSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self fitness_getDailyStepSamples:input callback:callback]; } RCT_EXPORT_METHOD(saveSteps:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self fitness_saveSteps:input callback:callback]; } RCT_EXPORT_METHOD(getDistanceWalkingRunning:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self fitness_getDistanceWalkingRunningOnDay:input callback:callback]; } RCT_EXPORT_METHOD(getDailyDistanceWalkingRunningSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self fitness_getDailyDistanceWalkingRunningSamples:input callback:callback]; } RCT_EXPORT_METHOD(getDistanceCycling:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self fitness_getDistanceCyclingOnDay:input callback:callback]; } RCT_EXPORT_METHOD(getDailyDistanceCyclingSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self fitness_getDailyDistanceCyclingSamples:input callback:callback]; } RCT_EXPORT_METHOD(getFlightsClimbed:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self fitness_getFlightsClimbedOnDay:input callback:callback]; } RCT_EXPORT_METHOD(getDailyFlightsClimbedSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self fitness_getDailyFlightsClimbedSamples:input callback:callback]; } RCT_EXPORT_METHOD(saveFood:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self saveFood:input callback:callback]; } RCT_EXPORT_METHOD(saveWater:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self saveWater:input callback:callback]; } RCT_EXPORT_METHOD(getHeartRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self vitals_getHeartRateSamples:input callback:callback]; } RCT_EXPORT_METHOD(getActiveEnergyBurned:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self activity_getActiveEnergyBurned:input callback:callback]; } RCT_EXPORT_METHOD(getBasalEnergyBurned:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self activity_getBasalEnergyBurned: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(getSleepSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self sleep_getSleepSamples:input callback:callback]; } RCT_EXPORT_METHOD(getInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self getModuleInfo:input callback:callback]; } RCT_EXPORT_METHOD(saveMindfulSession:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self mindfulness_saveMindfulSession:input callback:callback]; } - (void)isHealthKitAvailable:(RCTResponseSenderBlock)callback { BOOL isAvailable = NO; if ([HKHealthStore isHealthDataAvailable]) { isAvailable = YES; } callback(@[[NSNull null], @(isAvailable)]); } - (void)initializeHealthKit:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback { self.healthStore = [[HKHealthStore alloc] init]; if ([HKHealthStore isHealthDataAvailable]) { NSSet *writeDataTypes; NSSet *readDataTypes; // get permissions from input object provided by JS options argument NSDictionary* permissions =[input objectForKey:@"permissions"]; if(permissions != nil){ NSArray* readPermsArray = [permissions objectForKey:@"read"]; NSArray* writePermsArray = [permissions objectForKey:@"write"]; NSSet* readPerms = [self getReadPermsFromOptions:readPermsArray]; NSSet* writePerms = [self getWritePermsFromOptions:writePermsArray]; if(readPerms != nil) { readDataTypes = readPerms; } if(writePerms != nil) { writeDataTypes = writePerms; } } else { callback(@[RCTMakeError(@"permissions must be provided in the initialization options", nil, nil)]); return; } // make sure at least 1 read or write permission is provided if(!writeDataTypes && !readDataTypes){ callback(@[RCTMakeError(@"at least 1 read or write permission must be set in options.permissions", nil, nil)]); return; } [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)]); return; } else { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ callback(@[[NSNull null], @true]); }); } }]; } else { callback(@[RCTMakeError(@"HealthKit data is not available", nil, nil)]); } } - (void)getModuleInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback { NSDictionary *info = @{ @"name" : @"react-native-apple-healthkit", @"description" : @"A React Native bridge module for interacting with Apple HealthKit data", @"className" : @"RCTAppleHealthKit", @"author": @"Greg Wilson", }; callback(@[[NSNull null], info]); } @end