RCTAppleHealthKit.m 10.4 KB
Newer Older
1 2 3 4 5
//
//  RCTAppleHealthKit.m
//  RCTAppleHealthKit
//
//  Created by Greg Wilson on 2016-06-26.
EEvgeniiF's avatar
EEvgeniiF committed
6
//  Copyright © 2016 Greg Wilson. All rights reserved.
7 8 9 10 11
//

#import "RCTAppleHealthKit.h"
#import "RCTAppleHealthKit+TypesAndPermissions.h"

12
#import "RCTAppleHealthKit+Methods_Activity.h"
13 14
#import "RCTAppleHealthKit+Methods_Body.h"
#import "RCTAppleHealthKit+Methods_Fitness.h"
Hazem El-Sisy's avatar
Hazem El-Sisy committed
15
#import "RCTAppleHealthKit+Methods_Dietary.h"
16
#import "RCTAppleHealthKit+Methods_Characteristic.h"
17
#import "RCTAppleHealthKit+Methods_Vitals.h"
18
#import "RCTAppleHealthKit+Methods_Results.h"
19
#import "RCTAppleHealthKit+Methods_Sleep.h"
skleest's avatar
skleest committed
20
#import "RCTAppleHealthKit+Methods_Mindfulness.h"
21

22 23
#import <React/RCTBridgeModule.h>
#import <React/RCTEventDispatcher.h>
24

25
@implementation RCTAppleHealthKit
26

27 28
@synthesize bridge = _bridge;

29 30 31 32 33 34 35 36 37 38 39 40
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];
}

41 42 43 44 45
RCT_EXPORT_METHOD(checkSharePermission:(NSString *)input callback:(RCTResponseSenderBlock)callback)
{
    [self checkPermission:input callback:callback];
}

46 47 48 49 50
RCT_EXPORT_METHOD(initStepCountObserver:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_initializeStepEventObserver:input callback:callback];
}

51 52 53 54 55 56 57 58 59 60
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];
}

61
RCT_EXPORT_METHOD(getLatestWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
62
{
63
    [self body_getLatestWeight:input callback:callback];
64 65
}

66 67 68 69 70
RCT_EXPORT_METHOD(getWeightSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self body_getWeightSamples:input callback:callback];
}

71 72
RCT_EXPORT_METHOD(saveWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
73
    [self body_saveWeight:input callback:callback];
74 75
}

76
RCT_EXPORT_METHOD(getLatestHeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
77
{
78
    [self body_getLatestHeight:input callback:callback];
79 80
}

81 82 83 84 85
RCT_EXPORT_METHOD(getHeightSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self body_getHeightSamples:input callback:callback];
}

Greg Wilson's avatar
Greg Wilson committed
86 87 88 89
RCT_EXPORT_METHOD(saveHeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self body_saveHeight:input callback:callback];
}
90

91 92 93 94 95
RCT_EXPORT_METHOD(getLatestBmi:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self body_getLatestBodyMassIndex:input callback:callback];
}

96 97 98 99 100
RCT_EXPORT_METHOD(saveBmi:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self body_saveBodyMassIndex:input callback:callback];
}

101
RCT_EXPORT_METHOD(getLatestBodyFatPercentage:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
102
{
103
    [self body_getLatestBodyFatPercentage:input callback:callback];
104 105
}

106
RCT_EXPORT_METHOD(getLatestLeanBodyMass:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
107
{
108
    [self body_getLatestLeanBodyMass:input callback:callback];
109 110
}

111
RCT_EXPORT_METHOD(getStepCount:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
112
{
113
    [self fitness_getStepCountOnDay:input callback:callback];
114
}
115

116
RCT_EXPORT_METHOD(getSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
EEvgeniiF's avatar
EEvgeniiF committed
117
{
118
    [self fitness_getSamples:input callback:callback];
EEvgeniiF's avatar
EEvgeniiF committed
119 120
}

121
RCT_EXPORT_METHOD(setObserver:(NSDictionary *)input)
Evgenii Evstropov's avatar
Evgenii Evstropov committed
122
{
123
    [self fitness_setObserver:input];
Evgenii Evstropov's avatar
Evgenii Evstropov committed
124 125 126
}


127
RCT_EXPORT_METHOD(getDailyStepCountSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
128 129 130 131
{
    [self fitness_getDailyStepSamples:input callback:callback];
}

132 133 134 135 136
RCT_EXPORT_METHOD(saveSteps:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_saveSteps:input callback:callback];
}

137 138 139 140 141
RCT_EXPORT_METHOD(getDistanceWalkingRunning:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_getDistanceWalkingRunningOnDay:input callback:callback];
}

Jackson Tomlinson's avatar
Jackson Tomlinson committed
142 143 144 145 146
RCT_EXPORT_METHOD(getDailyDistanceWalkingRunningSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_getDailyDistanceWalkingRunningSamples:input callback:callback];
}

147 148 149 150 151
RCT_EXPORT_METHOD(getDistanceCycling:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_getDistanceCyclingOnDay:input callback:callback];
}

Jackson Tomlinson's avatar
Jackson Tomlinson committed
152 153 154 155 156
RCT_EXPORT_METHOD(getDailyDistanceCyclingSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_getDailyDistanceCyclingSamples:input callback:callback];
}

157 158 159 160 161
RCT_EXPORT_METHOD(getFlightsClimbed:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_getFlightsClimbedOnDay:input callback:callback];
}

Jackson Tomlinson's avatar
Jackson Tomlinson committed
162 163 164 165 166
RCT_EXPORT_METHOD(getDailyFlightsClimbedSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_getDailyFlightsClimbedSamples:input callback:callback];
}

Hazem El-Sisy's avatar
Hazem El-Sisy committed
167 168 169 170 171 172 173 174 175 176
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];
}

177 178 179 180 181
RCT_EXPORT_METHOD(getHeartRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self vitals_getHeartRateSamples:input callback:callback];
}

182 183 184 185 186
RCT_EXPORT_METHOD(getActiveEnergyBurned:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
   [self activity_getActiveEnergyBurned:input callback:callback];
}

hira's avatar
hira committed
187 188 189 190 191
RCT_EXPORT_METHOD(getBasalEnergyBurned:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self activity_getBasalEnergyBurned:input callback:callback];
}

192 193 194 195 196
RCT_EXPORT_METHOD(getBodyTemperatureSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self vitals_getBodyTemperatureSamples:input callback:callback];
}

197 198 199 200
RCT_EXPORT_METHOD(getBloodPressureSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self vitals_getBloodPressureSamples:input callback:callback];
}
201

202 203 204 205 206
RCT_EXPORT_METHOD(getRespiratoryRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self vitals_getRespiratoryRateSamples:input callback:callback];
}

207 208 209 210 211
RCT_EXPORT_METHOD(getBloodGlucoseSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self results_getBloodGlucoseSamples:input callback:callback];
}

212 213 214 215 216
RCT_EXPORT_METHOD(getSleepSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self sleep_getSleepSamples:input callback:callback];
}

217 218 219 220 221
RCT_EXPORT_METHOD(getInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self getModuleInfo:input callback:callback];
}

skleest's avatar
skleest committed
222 223 224 225 226
RCT_EXPORT_METHOD(saveMindfulSession:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self mindfulness_saveMindfulSession:input callback:callback];
}

227 228 229 230 231 232 233 234 235 236 237 238 239 240

- (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];
241

242
    if ([HKHealthStore isHealthDataAvailable]) {
243 244 245
        NSSet *writeDataTypes;
        NSSet *readDataTypes;

246
        // get permissions from input object provided by JS options argument
247 248 249 250 251 252
        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];
253

254 255 256 257 258 259
            if(readPerms != nil) {
                readDataTypes = readPerms;
            }
            if(writePerms != nil) {
                writeDataTypes = writePerms;
            }
260 261 262 263 264 265 266
        } 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){
267
            callback(@[RCTMakeError(@"at least 1 read or write permission must be set in options.permissions", nil, nil)]);
268
            return;
269
        }
270

271 272
        [self.healthStore requestAuthorizationToShareTypes:writeDataTypes readTypes:readDataTypes completion:^(BOOL success, NSError *error) {
            if (!success) {
273 274 275
                NSString *errMsg = [NSString stringWithFormat:@"Error with HealthKit authorization: %@", error];
                NSLog(errMsg);
                callback(@[RCTMakeError(errMsg, nil, nil)]);
276 277 278 279 280 281 282 283
                return;
            } else {
                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                    callback(@[[NSNull null], @true]);
                });
            }
        }];
    } else {
Greg Wilson's avatar
Greg Wilson committed
284
        callback(@[RCTMakeError(@"HealthKit data is not available", nil, nil)]);
285 286 287
    }
}

288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
- (void)checkPermission:(NSString *)input callback:(RCTResponseSenderBlock)callback
{
    self.healthStore = [[HKHealthStore alloc] init];
    if ([HKHealthStore isHealthDataAvailable]) {
        
        HKObjectType *val = [[self writePermsDict] objectForKey:input];
        
        if ([self.healthStore authorizationStatusForType:val] == HKAuthorizationStatusSharingAuthorized) {
            callback(@[[NSNull null], @true]);
        } else {
            callback(@[[NSNull null], @false]);
        }
    } else {
        callback(@[RCTMakeError(@"HealthKit data is not available", nil, nil)]);
    }
}

305 306
- (void)getModuleInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
307 308 309 310 311 312 313
    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]);
314 315 316
}

@end