From 0e8e84904d221f075abf9eeedb96ca594c1ffa82 Mon Sep 17 00:00:00 2001 From: Furyou81 Date: Wed, 30 Jan 2019 11:45:10 +0700 Subject: [PATCH] get the activity --- Constants/Permissions.js | 3 +- .../RCTAppleHealthKit+Methods_Activity.h | 4 +- .../RCTAppleHealthKit+Methods_Activity.m | 4 +- .../RCTAppleHealthKit+Methods_Body.m | 11 +- .../RCTAppleHealthKit+Methods_Fitness.h | 2 + .../RCTAppleHealthKit+Methods_Fitness.m | 46 ++++ RCTAppleHealthKit/RCTAppleHealthKit+Queries.h | 16 +- RCTAppleHealthKit/RCTAppleHealthKit+Queries.m | 194 ++++++++++++--- .../RCTAppleHealthKit+TypesAndPermissions.h | 2 + .../RCTAppleHealthKit+TypesAndPermissions.m | 6 +- RCTAppleHealthKit/RCTAppleHealthKit+Utils.h | 3 +- RCTAppleHealthKit/RCTAppleHealthKit+Utils.m | 235 ++++++++++++++---- RCTAppleHealthKit/RCTAppleHealthKit.h | 2 + RCTAppleHealthKit/RCTAppleHealthKit.m | 37 ++- 14 files changed, 462 insertions(+), 103 deletions(-) diff --git a/Constants/Permissions.js b/Constants/Permissions.js index a6e2d25..4d2fdc2 100644 --- a/Constants/Permissions.js +++ b/Constants/Permissions.js @@ -66,5 +66,6 @@ export const Permissions = { SleepAnalysis: "SleepAnalysis", StepCount: "StepCount", Steps: "Steps", - Weight: "Weight" + Weight: "Weight", + Workout: "Workout" } diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Activity.h b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Activity.h index 235e9c6..5bdecf4 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Activity.h +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Activity.h @@ -3,8 +3,10 @@ // RCTAppleHealthKit // // Created by Alexander Vallorosi on 4/27/17. -// Copyright © 2017 Alexander Vallorosi. All rights reserved. +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. // + #import "RCTAppleHealthKit.h" @interface RCTAppleHealthKit (Methods_Activity) diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Activity.m b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Activity.m index 03b2724..eeb0d91 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Activity.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Activity.m @@ -3,8 +3,8 @@ // RCTAppleHealthKit // // Created by Alexander Vallorosi on 4/27/17. -// Copyright © 2017 Alexander Vallorosi. All rights reserved. -// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. #import "RCTAppleHealthKit+Methods_Activity.h" #import "RCTAppleHealthKit+Queries.h" diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Body.m b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Body.m index ca11ae2..5a29a89 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Body.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Body.m @@ -18,9 +18,9 @@ { HKQuantityType *weightType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass]; - HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input]; + HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[HKUnit gramUnitWithMetricPrefix:HKMetricPrefixKilo]]; if(unit == nil){ - unit = [HKUnit poundUnit]; + unit = [HKUnit gramUnit]; } [self fetchMostRecentQuantitySampleOfType:weightType @@ -33,7 +33,6 @@ else { // Determine the weight in the required unit. double usersWeight = [mostRecentQuantity doubleValueForUnit:unit]; - NSDictionary *response = @{ @"value" : @(usersWeight), @"startDate" : [RCTAppleHealthKit buildISO8601StringFromDate:startDate], @@ -153,9 +152,9 @@ { HKQuantityType *heightType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight]; - HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input]; + HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[HKUnit meterUnitWithMetricPrefix:HKMetricPrefixCenti]];; if(unit == nil){ - unit = [HKUnit inchUnit]; + unit = [HKUnit meterUnit]; } [self fetchMostRecentQuantitySampleOfType:heightType @@ -219,7 +218,7 @@ double height = [RCTAppleHealthKit doubleValueFromOptions:input]; NSDate *sampleDate = [RCTAppleHealthKit dateFromOptionsDefaultNow:input]; - HKUnit *heightUnit = [RCTAppleHealthKit hkUnitFromOptions:input]; + HKUnit *heightUnit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[HKUnit inchUnit]];; if(heightUnit == nil){ heightUnit = [HKUnit inchUnit]; } diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.h b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.h index 48108d6..51449f8 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.h +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.h @@ -12,6 +12,8 @@ @interface RCTAppleHealthKit (Methods_Fitness) - (void)fitness_getStepCountOnDay:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; +- (void)fitness_getSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; +- (void)fitness_setObserver:(NSDictionary *)input; - (void)fitness_getDailyStepSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; - (void)fitness_saveSteps:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; - (void)fitness_initializeStepEventObserver:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.m b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.m index 7996b82..c1fe790 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.m @@ -49,6 +49,52 @@ }]; } +- (void)fitness_getSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback +{ + HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[HKUnit countUnit]]; + NSUInteger limit = [RCTAppleHealthKit uintFromOptions:input key:@"limit" withDefault:HKObjectQueryNoLimit]; + BOOL ascending = [RCTAppleHealthKit boolFromOptions:input key:@"ascending" withDefault:false]; + NSString *type = [RCTAppleHealthKit stringFromOptions:input key:@"type" withDefault:@"Walking"]; + NSDate *startDate = [RCTAppleHealthKit dateFromOptions:input key:@"startDate" withDefault:[NSDate date]]; + NSDate *endDate = [RCTAppleHealthKit dateFromOptions:input key:@"endDate" withDefault:[NSDate date]]; + + NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:startDate endDate:endDate options:HKQueryOptionStrictStartDate]; + + HKSampleType *samplesType = [RCTAppleHealthKit hkQuantityTypeFromString:type]; + if ([type isEqual:@"Running"] || [type isEqual:@"Cycling"]) { + unit = [HKUnit mileUnit]; + } + NSLog(@"error getting samples: %@", [samplesType identifier]); + [self fetchSamplesOfType:samplesType + unit:unit + predicate:predicate + ascending:ascending + limit:limit + completion:^(NSArray *results, NSError *error) { + if(results){ + callback(@[[NSNull null], results]); + return; + } else { + NSLog(@"error getting samples: %@", error); + callback(@[RCTMakeError(@"error getting samples", nil, nil)]); + return; + } + }]; +} + +- (void)fitness_setObserver:(NSDictionary *)input +{ + HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[HKUnit countUnit]]; + NSString *type = [RCTAppleHealthKit stringFromOptions:input key:@"type" withDefault:@"Walking"]; + + HKSampleType *samplesType = [RCTAppleHealthKit hkQuantityTypeFromString:type]; + if ([type isEqual:@"Running"] || [type isEqual:@"Cycling"]) { + unit = [HKUnit mileUnit]; + } + + [self setObserverForType:samplesType unit:unit]; +} + - (void)fitness_getDailyStepSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback { diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Queries.h b/RCTAppleHealthKit/RCTAppleHealthKit+Queries.h index e01ee81..8546474 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Queries.h +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Queries.h @@ -19,6 +19,18 @@ startDate:(NSDate *)startDate endDate:(NSDate *)endDate completion:(void (^)(NSArray *, NSError *))completionHandler; + + +- (void)fetchSamplesOfType:(HKSampleType *)quantityType + unit:(HKUnit *)unit + predicate:(NSPredicate *)predicate + ascending:(BOOL)asc + limit:(NSUInteger)lim + completion:(void (^)(NSArray *, NSError *))completion; +- (void)setObserverForType:(HKSampleType *)quantityType + unit:(HKUnit *)unit; + + - (void)fetchQuantitySamplesOfType:(HKQuantityType *)quantityType unit:(HKUnit *)unit predicate:(NSPredicate *)predicate @@ -33,7 +45,7 @@ completion:(void (^)(NSArray *, NSError *))completion; - (void)fetchCumulativeSumStatisticsCollection:(HKQuantityType *)quantityType unit:(HKUnit *)unit - startDate:(NSDate *)startDate + startDate:(NSDate *)startDate endDate:(NSDate *)endDate ascending:(BOOL)asc limit:(NSUInteger)lim @@ -46,6 +58,8 @@ ascending:(BOOL)asc limit:(NSUInteger)lim completion:(void (^)(NSArray *, NSError *))completionHandler; + + - (void)fetchSleepCategorySamplesForPredicate:(NSPredicate *)predicate limit:(NSUInteger)lim completion:(void (^)(NSArray *, NSError *))completion; diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Queries.m b/RCTAppleHealthKit/RCTAppleHealthKit+Queries.m index f63cbb7..5e3ca96 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Queries.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Queries.m @@ -10,8 +10,10 @@ #import "RCTAppleHealthKit+Queries.h" #import "RCTAppleHealthKit+Utils.h" -@implementation RCTAppleHealthKit (Queries) +#import +#import +@implementation RCTAppleHealthKit (Queries) - (void)fetchMostRecentQuantitySampleOfType:(HKQuantityType *)quantityType predicate:(NSPredicate *)predicate @@ -49,7 +51,6 @@ [self.healthStore executeQuery:query]; } - - (void)fetchQuantitySamplesOfType:(HKQuantityType *)quantityType unit:(HKUnit *)unit predicate:(NSPredicate *)predicate @@ -106,19 +107,152 @@ [self.healthStore executeQuery:query]; } +- (void)fetchSamplesOfType:(HKSampleType *)type + 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(), ^{ + if (type == [HKObjectType workoutType]) { + for (HKWorkout *sample in results) { + double energy = [[sample totalEnergyBurned] doubleValueForUnit:[HKUnit kilocalorieUnit]]; + double distance = [[sample totalDistance] doubleValueForUnit:[HKUnit mileUnit]]; + NSString *type = [RCTAppleHealthKit stringForHKWorkoutActivityType:[sample workoutActivityType]]; + + NSString *startDateString = [RCTAppleHealthKit buildISO8601StringFromDate:sample.startDate]; + NSString *endDateString = [RCTAppleHealthKit buildISO8601StringFromDate:sample.endDate]; + + bool isTracked = true; + if ([[sample metadata][HKMetadataKeyWasUserEntered] intValue] == 1) { + isTracked = false; + } + + NSString* device = @""; + if (@available(iOS 11.0, *)) { + device = [[sample sourceRevision] productType]; + } else { + device = [[sample device] name]; + if (!device) { + device = @"iPhone"; + } + } + + NSDictionary *elem = @{ + @"activityName" : [NSNumber numberWithInt:[sample workoutActivityType]], + @"calories" : @(energy), + @"tracked" : @(isTracked), + @"sourceName" : [[[sample sourceRevision] source] name], + @"sourceId" : [[[sample sourceRevision] source] bundleIdentifier], + @"device": device, + @"distance" : @(distance), + @"start" : startDateString, + @"end" : endDateString + }; + + [data addObject:elem]; + } + } else { + for (HKQuantitySample *sample in results) { + HKQuantity *quantity = sample.quantity; + double value = [quantity doubleValueForUnit:unit]; + + NSString * valueType = @"quantity"; + if (unit == [HKUnit mileUnit]) { + valueType = @"distance"; + } + + NSString *startDateString = [RCTAppleHealthKit buildISO8601StringFromDate:sample.startDate]; + NSString *endDateString = [RCTAppleHealthKit buildISO8601StringFromDate:sample.endDate]; + + bool isTracked = true; + if ([[sample metadata][HKMetadataKeyWasUserEntered] intValue] == 1) { + isTracked = false; + } + + NSString* device = @""; + if (@available(iOS 11.0, *)) { + device = [[sample sourceRevision] productType]; + } else { + device = [[sample device] name]; + if (!device) { + device = @"iPhone"; + } + } + + NSDictionary *elem = @{ + valueType : @(value), + @"tracked" : @(isTracked), + @"sourceName" : [[[sample sourceRevision] source] name], + @"sourceId" : [[[sample sourceRevision] source] bundleIdentifier], + @"device": device, + @"start" : startDateString, + @"end" : endDateString + }; + + [data addObject:elem]; + } + } + + completion(data, error); + }); + } + }; + + HKSampleQuery *query = [[HKSampleQuery alloc] initWithSampleType:type + predicate:predicate + limit:lim + sortDescriptors:@[timeSortDescriptor] + resultsHandler:handlerBlock]; + + [self.healthStore executeQuery:query]; +} - - - - - - +- (void)setObserverForType:(HKSampleType *)type + unit:(HKUnit *)unit { + HKObserverQuery *query = [[HKObserverQuery alloc] initWithSampleType:type predicate:nil updateHandler:^(HKObserverQuery *query, HKObserverQueryCompletionHandler completionHandler, NSError * _Nullable error){ + if (error) { + NSLog(@"*** An error occured while setting up the stepCount observer. %@ ***", error.localizedDescription); + return; + } + [self.bridge.eventDispatcher sendAppEventWithName:@"observer" body:@""]; + + // Theoretically, HealthKit expect that copletionHandler would be called at the end of query process, + // but it's unclear how to do in in event paradigm + +// dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 5); +// dispatch_after(delay, dispatch_get_main_queue(), ^(void){ +// completionHandler(); +// }); + }]; + + [self.healthStore executeQuery:query]; + [self.healthStore enableBackgroundDeliveryForType:type frequency:HKUpdateFrequencyImmediate withCompletion:^(BOOL success, NSError * _Nullable error) { + NSLog(@"success %s print some error %@", success ? "true" : "false", [error localizedDescription]); + }]; +} - (void)fetchSleepCategorySamplesForPredicate:(NSPredicate *)predicate limit:(NSUInteger)lim completion:(void (^)(NSArray *, NSError *))completion { - NSSortDescriptor *timeSortDescriptor = [[NSSortDescriptor alloc] initWithKey:HKSampleSortIdentifierEndDate ascending:false]; @@ -293,12 +427,9 @@ unit:(HKUnit *)unit day:(NSDate *)day completion:(void (^)(double, NSDate *, NSDate *, NSError *))completionHandler { - NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"metadata.%K != YES", HKMetadataKeyWasUserEntered]; - //NSPredicate *predicate = - NSPredicate *predicate2 = [RCTAppleHealthKit predicateForSamplesOnDay:day]; - NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates: @[predicate1, predicate2]]; - HKStatisticsQuery *query = [[HKStatisticsQuery alloc] initWithQuantityType:quantityType - // predicate:p + + NSPredicate *predicate = [RCTAppleHealthKit predicateForSamplesOnDay:day]; + HKStatisticsQuery *query = [[HKStatisticsQuery alloc] initWithQuantityType:quantityType quantitySamplePredicate:predicate options:HKStatisticsOptionCumulativeSum completionHandler:^(HKStatisticsQuery *query, HKStatistics *result, NSError *error) { @@ -306,19 +437,6 @@ NSDate *startDate = result.startDate; NSDate *endDate = result.endDate; if (completionHandler) { - - printf("HELOOOOOOOOOOOOOO"); - NSLog(@"%@",result.sources); - for (HKSource *source in result.sources) - { - printf("%s", source.bundleIdentifier); - // if (![source.bundleIdentifier isEqualToString:@"com.apple.Health"]) - // { - // [dataSources addObject:source]; - // } - } - printf("HELOOOOOOOOOOOOOO"); - double value = [sum doubleValueForUnit:unit]; completionHandler(value,startDate, endDate, error); } @@ -336,16 +454,16 @@ NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *interval = [[NSDateComponents alloc] init]; - interval.hour = 1; - NSPredicate *predicate = [NSPredicate predicateWithFormat:@"metadata.%K != YES", HKMetadataKeyWasUserEntered]; - NSDateComponents *anchorComponents = [calendar components:NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear + interval.day = 1; + + NSDateComponents *anchorComponents = [calendar components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]]; - //anchorComponents.hour = 0; + anchorComponents.hour = 0; NSDate *anchorDate = [calendar dateFromComponents:anchorComponents]; // Create the query HKStatisticsCollectionQuery *query = [[HKStatisticsCollectionQuery alloc] initWithQuantityType:quantityType - quantitySamplePredicate:predicate + quantitySamplePredicate:nil options:HKStatisticsOptionCumulativeSum anchorDate:anchorDate intervalComponents:interval]; @@ -391,16 +509,16 @@ NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *interval = [[NSDateComponents alloc] init]; - interval.hour = 1; + interval.day = 1; - NSDateComponents *anchorComponents = [calendar components:NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear + NSDateComponents *anchorComponents = [calendar components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]]; - //anchorComponents.hour = 0; + anchorComponents.hour = 0; NSDate *anchorDate = [calendar dateFromComponents:anchorComponents]; -NSPredicate *predicate = [NSPredicate predicateWithFormat:@"metadata.%K != YES", HKMetadataKeyWasUserEntered]; + // Create the query HKStatisticsCollectionQuery *query = [[HKStatisticsCollectionQuery alloc] initWithQuantityType:quantityType - quantitySamplePredicate:predicate + quantitySamplePredicate:nil options:HKStatisticsOptionCumulativeSum anchorDate:anchorDate intervalComponents:interval]; diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.h b/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.h index 5cb0891..d69b7e9 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.h +++ b/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.h @@ -11,6 +11,8 @@ @interface RCTAppleHealthKit (TypesAndPermissions) +- (NSDictionary *)readPermsDict; +- (NSDictionary *)writePermsDict; - (NSSet *)getReadPermsFromOptions:(NSArray *)options; - (NSSet *)getWritePermsFromOptions:(NSArray *)options; diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.m b/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.m index 450c033..6cb5a05 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.m @@ -3,7 +3,8 @@ // RCTAppleHealthKit // // Created by Greg Wilson on 2016-06-26. -// Copyright © 2016 Greg Wilson. All rights reserved. +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. // #import "RCTAppleHealthKit+TypesAndPermissions.h" @@ -49,6 +50,8 @@ @"SleepAnalysis" : [HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierSleepAnalysis], // Mindfulness @"MindfulSession" : [HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierMindfulSession], + //workouts + @"Workout" : [HKObjectType workoutType], }; return readPerms; } @@ -118,7 +121,6 @@ return writePerms; } - // Returns HealthKit read permissions from options array - (NSSet *)getReadPermsFromOptions:(NSArray *)options { NSDictionary *readPermDict = [self readPermsDict]; diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Utils.h b/RCTAppleHealthKit/RCTAppleHealthKit+Utils.h index 4501675..7d00c78 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Utils.h +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Utils.h @@ -23,7 +23,7 @@ + (NSDate *)startDateFromOptions:(NSDictionary *)options; + (NSDate *)endDateFromOptions:(NSDictionary *)options; + (NSDate *)endDateFromOptionsDefaultNow:(NSDictionary *)options; -+ (HKUnit *)hkUnitFromOptions:(NSDictionary *)options; ++ (HKSampleType *)hkQuantityTypeFromString:(NSString *)type; + (HKUnit *)hkUnitFromOptions:(NSDictionary *)options key:(NSString *)key withDefault:(HKUnit *)defaultValue; + (NSUInteger)uintFromOptions:(NSDictionary *)options key:(NSString *)key withDefault:(NSUInteger)defaultValue; @@ -33,5 +33,6 @@ + (bool)boolFromOptions:(NSDictionary *)options key:(NSString *)key withDefault:(bool)defaultValue; + (NSMutableArray *)reverseNSMutableArray:(NSMutableArray *)array; ++ (NSString*) stringForHKWorkoutActivityType:(int) enumValue; @end diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Utils.m b/RCTAppleHealthKit/RCTAppleHealthKit+Utils.m index 7e0a834..f3a2f22 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Utils.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Utils.m @@ -124,56 +124,20 @@ return date; } -// ========== -// DEPRECATED -// ========== -+ (HKUnit *)hkUnitFromOptions:(NSDictionary *)options { - NSString *unitString = [options objectForKey:@"unit"]; - HKUnit *theUnit; - - if([unitString isEqualToString:@"gram"]){ - theUnit = [HKUnit gramUnit]; - } - if([unitString isEqualToString:@"pound"]){ - theUnit = [HKUnit poundUnit]; - } - if([unitString isEqualToString:@"meter"]){ - theUnit = [HKUnit meterUnit]; - } - if([unitString isEqualToString:@"mile"]){ - theUnit = [HKUnit mileUnit]; - } - if([unitString isEqualToString:@"inch"]){ - theUnit = [HKUnit inchUnit]; - } - if([unitString isEqualToString:@"foot"]){ - theUnit = [HKUnit footUnit]; - } - if([unitString isEqualToString:@"second"]){ - theUnit = [HKUnit secondUnit]; - } - if([unitString isEqualToString:@"minute"]){ - theUnit = [HKUnit minuteUnit]; - } - if([unitString isEqualToString:@"hour"]){ - theUnit = [HKUnit hourUnit]; - } - if([unitString isEqualToString:@"day"]){ - theUnit = [HKUnit dayUnit]; - } - if([unitString isEqualToString:@"joule"]){ - theUnit = [HKUnit jouleUnit]; - } - if([unitString isEqualToString:@"calorie"]){ - theUnit = [HKUnit calorieUnit]; - } - if([unitString isEqualToString:@"count"]){ - theUnit = [HKUnit countUnit]; - } - if([unitString isEqualToString:@"percent"]){ - theUnit = [HKUnit percentUnit]; - } - return theUnit; ++ (HKSampleType *)hkQuantityTypeFromString:(NSString *)type { + if ([type isEqual:@"Walking"]) { + return [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]; + } else if ([type isEqual:@"StairClimbing"]) { + return [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierFlightsClimbed]; + } else if ([type isEqual:@"Running"]){ + return [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDistanceWalkingRunning]; + } else if ([type isEqual:@"Cycling"]){ + return [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDistanceCycling]; + } else if ([type isEqual:@"Swimming"]){ + return [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDistanceSwimming]; + } + // default [type isEqual:@"Workout"]) + return [HKObjectType workoutType]; } @@ -184,12 +148,21 @@ if([unitString isEqualToString:@"gram"]){ theUnit = [HKUnit gramUnit]; } + if([unitString isEqualToString:@"kg"]){ + theUnit = [HKUnit gramUnitWithMetricPrefix:HKMetricPrefixKilo]; + } + if([unitString isEqualToString:@"stone"]){ + theUnit = [HKUnit stoneUnit]; + } if([unitString isEqualToString:@"pound"]){ theUnit = [HKUnit poundUnit]; } if([unitString isEqualToString:@"meter"]){ theUnit = [HKUnit meterUnit]; } + if([unitString isEqualToString:@"cm"]){ + theUnit = [HKUnit meterUnitWithMetricPrefix:HKMetricPrefixCenti]; + } if([unitString isEqualToString:@"inch"]){ theUnit = [HKUnit inchUnit]; } @@ -321,4 +294,166 @@ return array; } ++ (NSString*)stringForHKWorkoutActivityType:(int) enumValue{ + switch( enumValue ){ + case HKWorkoutActivityTypeAmericanFootball: + return @"AmericanFootball"; + case HKWorkoutActivityTypeArchery: + return @"Archery"; + case HKWorkoutActivityTypeAustralianFootball: + return @"AustralianFootball"; + case HKWorkoutActivityTypeBadminton: + return @"Badminton"; + case HKWorkoutActivityTypeBaseball: + return @"Baseball"; + case HKWorkoutActivityTypeBasketball: + return @"Basketball"; + case HKWorkoutActivityTypeBowling: + return @"Bowling"; + case HKWorkoutActivityTypeBoxing: + return @"Boxing"; + case HKWorkoutActivityTypeClimbing: + return @"Climbing"; + case HKWorkoutActivityTypeCricket: + return @"Cricket"; + case HKWorkoutActivityTypeCrossTraining: + return @"CrossTraining"; + case HKWorkoutActivityTypeCurling: + return @"Curling"; + case HKWorkoutActivityTypeCycling: + return @"Cycling"; + case HKWorkoutActivityTypeDance: + return @"Dance"; + case HKWorkoutActivityTypeDanceInspiredTraining: + return @"DanceInspiredTraining"; + case HKWorkoutActivityTypeElliptical: + return @"Elliptical"; + case HKWorkoutActivityTypeEquestrianSports: + return @"EquestrianSports"; + case HKWorkoutActivityTypeFencing: + return @"Fencing"; + case HKWorkoutActivityTypeFishing: + return @"Fishing"; + case HKWorkoutActivityTypeFunctionalStrengthTraining: + return @"FunctionalStrengthTraining"; + case HKWorkoutActivityTypeGolf: + return @"Golf"; + case HKWorkoutActivityTypeGymnastics: + return @"Gymnastics"; + case HKWorkoutActivityTypeHandball: + return @"Handball"; + case HKWorkoutActivityTypeHiking: + return @"Hiking"; + case HKWorkoutActivityTypeHockey: + return @"Hockey"; + case HKWorkoutActivityTypeHunting: + return @"Hunting"; + case HKWorkoutActivityTypeLacrosse: + return @"Lacrosse"; + case HKWorkoutActivityTypeMartialArts: + return @"MartialArts"; + case HKWorkoutActivityTypeMindAndBody: + return @"MindAndBody"; + case HKWorkoutActivityTypeMixedMetabolicCardioTraining: + return @"MixedMetabolicCardioTraining"; + case HKWorkoutActivityTypePaddleSports: + return @"PaddleSports"; + case HKWorkoutActivityTypePlay: + return @"Play"; + case HKWorkoutActivityTypePreparationAndRecovery: + return @"PreparationAndRecovery"; + case HKWorkoutActivityTypeRacquetball: + return @"Racquetball"; + case HKWorkoutActivityTypeRowing: + return @"Rowing"; + case HKWorkoutActivityTypeRugby: + return @"Rugby"; + case HKWorkoutActivityTypeRunning: + return @"Running"; + case HKWorkoutActivityTypeSailing: + return @"Sailing"; + case HKWorkoutActivityTypeSkatingSports: + return @"SkatingSports"; + case HKWorkoutActivityTypeSnowSports: + return @"SnowSports"; + case HKWorkoutActivityTypeSoccer: + return @"Soccer"; + case HKWorkoutActivityTypeSoftball: + return @"Softball"; + case HKWorkoutActivityTypeSquash: + return @"Squash"; + case HKWorkoutActivityTypeStairClimbing: + return @"StairClimbing"; + case HKWorkoutActivityTypeSurfingSports: + return @"SurfingSports"; + case HKWorkoutActivityTypeSwimming: + return @"Swimming"; + case HKWorkoutActivityTypeTableTennis: + return @"TableTennis"; + case HKWorkoutActivityTypeTennis: + return @"Tennis"; + case HKWorkoutActivityTypeTrackAndField: + return @"TrackAndField"; + case HKWorkoutActivityTypeTraditionalStrengthTraining: + return @"TraditionalStrengthTraining"; + case HKWorkoutActivityTypeVolleyball: + return @"Volleyball"; + case HKWorkoutActivityTypeWalking: + return @"Walking"; + case HKWorkoutActivityTypeWaterFitness: + return @"WaterFitness"; + case HKWorkoutActivityTypeWaterPolo: + return @"WaterPolo"; + case HKWorkoutActivityTypeWaterSports: + return @"WaterSports"; + case HKWorkoutActivityTypeWrestling: + return @"Wrestling"; + case HKWorkoutActivityTypeYoga: + return @"Yoga"; + case HKWorkoutActivityTypeOther: + return @"Other"; + case HKWorkoutActivityTypeBarre: + return @"Barre"; + case HKWorkoutActivityTypeCoreTraining: + return @"CoreTraining"; + case HKWorkoutActivityTypeCrossCountrySkiing: + return @"CrossCountrySkiing"; + case HKWorkoutActivityTypeDownhillSkiing: + return @"DownhillSkiing"; + case HKWorkoutActivityTypeFlexibility: + return @"Flexibility"; + case HKWorkoutActivityTypeHighIntensityIntervalTraining: + return @"HighIntensityIntervalTraining"; + case HKWorkoutActivityTypeJumpRope: + return @"JumpRope"; + case HKWorkoutActivityTypeKickboxing: + return @"Kickboxing"; + case HKWorkoutActivityTypePilates: + return @"Pilates"; + case HKWorkoutActivityTypeSnowboarding: + return @"Snowboarding"; + case HKWorkoutActivityTypeStairs: + return @"Stairs"; + case HKWorkoutActivityTypeStepTraining: + return @"StepTraining"; + case HKWorkoutActivityTypeWheelchairWalkPace: + return @"WheelchairWalkPace"; + case HKWorkoutActivityTypeWheelchairRunPace: + return @"WheelchairRunPace"; + case HKWorkoutActivityTypeTaiChi: + return @"TaiChi"; + case HKWorkoutActivityTypeMixedCardio: + return @"MixedCardio"; + case HKWorkoutActivityTypeHandCycling: + return @"HandCycling"; + default:{ + NSException *e = [NSException + exceptionWithName:@"HKWorkoutActivityType InvalidValue" + reason:@"HKWorkoutActivityType can only have a value from the HKWorkoutActivityType enum" + userInfo:nil]; + @throw e; + } + } +} + @end diff --git a/RCTAppleHealthKit/RCTAppleHealthKit.h b/RCTAppleHealthKit/RCTAppleHealthKit.h index 27b8c03..6ccbe26 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit.h +++ b/RCTAppleHealthKit/RCTAppleHealthKit.h @@ -16,9 +16,11 @@ @interface RCTAppleHealthKit : NSObject @property (nonatomic) HKHealthStore *healthStore; +@property BOOL isSync; - (void)isHealthKitAvailable:(RCTResponseSenderBlock)callback; - (void)initializeHealthKit:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; +- (void)checkPermission:(NSString *)input callback:(RCTResponseSenderBlock)callback; - (void)getModuleInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; @end diff --git a/RCTAppleHealthKit/RCTAppleHealthKit.m b/RCTAppleHealthKit/RCTAppleHealthKit.m index ccc4c26..5ef4ecc 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit.m @@ -3,7 +3,8 @@ // RCTAppleHealthKit // // Created by Greg Wilson on 2016-06-26. -// Copyright © 2016 Greg Wilson. All rights reserved. +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. // #import "RCTAppleHealthKit.h" @@ -23,6 +24,7 @@ #import @implementation RCTAppleHealthKit + @synthesize bridge = _bridge; RCT_EXPORT_MODULE(); @@ -37,6 +39,11 @@ RCT_EXPORT_METHOD(initHealthKit:(NSDictionary *)input callback:(RCTResponseSende [self initializeHealthKit:input callback:callback]; } +RCT_EXPORT_METHOD(checkSharePermission:(NSString *)input callback:(RCTResponseSenderBlock)callback) +{ + [self checkPermission:input callback:callback]; +} + RCT_EXPORT_METHOD(initStepCountObserver:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self fitness_initializeStepEventObserver:input callback:callback]; @@ -107,6 +114,17 @@ RCT_EXPORT_METHOD(getStepCount:(NSDictionary *)input callback:(RCTResponseSender [self fitness_getStepCountOnDay:input callback:callback]; } +RCT_EXPORT_METHOD(getSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) +{ + [self fitness_getSamples:input callback:callback]; +} + +RCT_EXPORT_METHOD(setObserver:(NSDictionary *)input) +{ + [self fitness_setObserver:input]; +} + + RCT_EXPORT_METHOD(getDailyStepCountSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self fitness_getDailyStepSamples:input callback:callback]; @@ -268,6 +286,23 @@ RCT_EXPORT_METHOD(saveMindfulSession:(NSDictionary *)input callback:(RCTResponse } } +- (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)]); + } +} + - (void)getModuleInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback { NSDictionary *info = @{ -- 2.26.2