RCTAppleHealthKit.m 9.64 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
//
//  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"

12 13
#import "RCTAppleHealthKit+Methods_Body.h"
#import "RCTAppleHealthKit+Methods_Fitness.h"
14
#import "RCTAppleHealthKit+Methods_Characteristic.h"
15
#import "RCTAppleHealthKit+Methods_Vitals.h"
16
#import "RCTAppleHealthKit+Methods_Results.h"
17
#import "RCTAppleHealthKit+Methods_Sleep.h"
skleest's avatar
skleest committed
18
#import "RCTAppleHealthKit+Methods_Mindfulness.h"
19
#import "RCTAppleHealthKit+NSUserDefaults.h"
20

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

24
@implementation RCTAppleHealthKit
25 26
@synthesize bridge = _bridge;

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

39 40 41 42 43
RCT_EXPORT_METHOD(initStepCountObserver:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_initializeStepEventObserver:input callback:callback];
}

44 45 46 47 48 49 50 51 52 53
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];
}

54
RCT_EXPORT_METHOD(getLatestWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
55
{
56
    [self body_getLatestWeight:input callback:callback];
57 58
}

59 60 61 62 63
RCT_EXPORT_METHOD(getWeightSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self body_getWeightSamples:input callback:callback];
}

64 65
RCT_EXPORT_METHOD(saveWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
66
    [self body_saveWeight:input callback:callback];
67 68
}

69
RCT_EXPORT_METHOD(getLatestHeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
70
{
71
    [self body_getLatestHeight:input callback:callback];
72 73
}

74 75 76 77 78
RCT_EXPORT_METHOD(getHeightSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self body_getHeightSamples:input callback:callback];
}

Greg Wilson's avatar
Greg Wilson committed
79 80 81 82
RCT_EXPORT_METHOD(saveHeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self body_saveHeight:input callback:callback];
}
83

84 85 86 87 88
RCT_EXPORT_METHOD(getLatestBmi:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self body_getLatestBodyMassIndex:input callback:callback];
}

89 90 91 92 93
RCT_EXPORT_METHOD(saveBmi:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self body_saveBodyMassIndex:input callback:callback];
}

94
RCT_EXPORT_METHOD(getLatestBodyFatPercentage:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
95
{
96
    [self body_getLatestBodyFatPercentage:input callback:callback];
97 98
}

99
RCT_EXPORT_METHOD(getLatestLeanBodyMass:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
100
{
101
    [self body_getLatestLeanBodyMass:input callback:callback];
102 103
}

104
RCT_EXPORT_METHOD(getStepCount:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
105
{
106
    [self fitness_getStepCountOnDay:input callback:callback];
107
}
108

109 110 111 112 113
RCT_EXPORT_METHOD(getStepCountSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_geStepSamples:input callback:callback];
}

114 115 116 117 118
RCT_EXPORT_METHOD(getStepCountSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_geStepSamplesByAnchor:input callback:callback];
}

119
RCT_EXPORT_METHOD(getDailyStepCountSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
120 121 122 123
{
    [self fitness_getDailyStepSamples:input callback:callback];
}

124 125 126 127 128
RCT_EXPORT_METHOD(saveSteps:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_saveSteps:input callback:callback];
}

129 130 131 132 133
RCT_EXPORT_METHOD(getDistanceWalkingRunning:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_getDistanceWalkingRunningOnDay:input callback:callback];
}

134 135 136 137 138 139 140 141 142 143
RCT_EXPORT_METHOD(getDistanceCycling:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_getDistanceCyclingOnDay:input callback:callback];
}

RCT_EXPORT_METHOD(getFlightsClimbed:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self fitness_getFlightsClimbedOnDay:input callback:callback];
}

144 145 146 147 148
RCT_EXPORT_METHOD(getHeartRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self vitals_getHeartRateSamples:input callback:callback];
}

149 150 151 152 153
RCT_EXPORT_METHOD(getHeartRateSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self vitals_getHeartRateSamplesByAnchor:input callback:callback];
}

154 155 156 157 158
RCT_EXPORT_METHOD(getBodyTemperatureSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self vitals_getBodyTemperatureSamples:input callback:callback];
}

159 160 161 162
RCT_EXPORT_METHOD(getBloodPressureSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self vitals_getBloodPressureSamples:input callback:callback];
}
163

164 165 166 167 168
RCT_EXPORT_METHOD(getBloodPressureSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self vitals_getBloodPressureSamplesByAnchor:input callback:callback];
}

169 170 171 172 173
RCT_EXPORT_METHOD(getRespiratoryRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self vitals_getRespiratoryRateSamples:input callback:callback];
}

174 175 176 177 178
RCT_EXPORT_METHOD(getBloodGlucoseSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self results_getBloodGlucoseSamples:input callback:callback];
}

179 180 181
RCT_EXPORT_METHOD(getSleepSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self sleep_getSleepSamples:input callback:callback];
182 183 184 185 186
}

RCT_EXPORT_METHOD(getSleepSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self sleep_getSleepSamplesByAnchor:input callback:callback];
187 188
}

189 190 191 192 193
RCT_EXPORT_METHOD(getInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self getModuleInfo:input callback:callback];
}

skleest's avatar
skleest committed
194 195 196 197 198
RCT_EXPORT_METHOD(saveMindfulSession:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self mindfulness_saveMindfulSession:input callback:callback];
}

199 200 201 202 203 204 205 206 207
RCT_EXPORT_METHOD(setUserDefaults:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self set_UserDefaultsByKey:input callback:callback];
}

RCT_EXPORT_METHOD(resetUserDefaults:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self reset_UserDefaultsByKey:input callback:callback];
}
208

王品堯's avatar
王品堯 committed
209 210 211 212 213 214 215 216 217 218
RCT_EXPORT_METHOD(getLastTimestamp:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self get_TimestampByKey:input callback:callback];
}

RCT_EXPORT_METHOD(setTimestamp:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
    [self set_TimestampByKey:input callback:callback];
}

219 220 221 222 223 224 225 226 227 228 229 230 231
- (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];
232

233
    if ([HKHealthStore isHealthDataAvailable]) {
234 235 236
        NSSet *writeDataTypes;
        NSSet *readDataTypes;

237
        // get permissions from input object provided by JS options argument
238 239 240 241 242 243
        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];
244

245 246 247 248 249 250
            if(readPerms != nil) {
                readDataTypes = readPerms;
            }
            if(writePerms != nil) {
                writeDataTypes = writePerms;
            }
251 252 253 254 255 256 257
        } 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){
258
            callback(@[RCTMakeError(@"at least 1 read or write permission must be set in options.permissions", nil, nil)]);
259
            return;
260
        }
261

262 263
        [self.healthStore requestAuthorizationToShareTypes:writeDataTypes readTypes:readDataTypes completion:^(BOOL success, NSError *error) {
            if (!success) {
264 265 266
                NSString *errMsg = [NSString stringWithFormat:@"Error with HealthKit authorization: %@", error];
                NSLog(errMsg);
                callback(@[RCTMakeError(errMsg, nil, nil)]);
267 268 269 270 271 272 273 274
                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
275
        callback(@[RCTMakeError(@"HealthKit data is not available", nil, nil)]);
276 277 278 279 280
    }
}

- (void)getModuleInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
281 282 283 284 285 286 287
    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]);
288 289 290
}

@end