diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.h b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.h index 108450cf0d1def81906e0e184467a194247d3b49..e358b9e142a4a26916c95a3474beb6d9189cda96 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.h +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.h @@ -12,6 +12,7 @@ - (void)fitness_getStepCountOnDay:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; - (void)fitness_geStepSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; +- (void)fitness_geStepSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; - (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 04c19d39c5a94045e3f2ce86bbc6b3b29c7f0e5b..92ccf2b775f743a453621cae250edabbc0c7c708 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Fitness.m @@ -75,13 +75,45 @@ callback(@[[NSNull null], results]); return; } else { - NSLog(@"error getting heart rate samples: %@", error); - callback(@[RCTMakeError(@"error getting heart rate samples", nil, nil)]); + NSLog(@"error getting step samples: %@", error); + callback(@[RCTMakeError(@"error getting step samples", nil, nil)]); return; } }]; } +- (void)fitness_geStepSamplesByAnchor:(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]; + NSDate *startDate = [RCTAppleHealthKit dateFromOptions:input key:@"startDate" withDefault:nil]; + NSDate *endDate = [RCTAppleHealthKit dateFromOptions:input key:@"endDate" withDefault:[NSDate date]]; + if(startDate == nil){ + callback(@[RCTMakeError(@"startDate is required in options", nil, nil)]); + return; + } + + HKQuantityType *stepCountType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]; + + NSPredicate * predicate = [RCTAppleHealthKit predicateForSamplesBetweenDates:startDate endDate:endDate]; + + [self fetchQuantitySamplesOfTypeByAnchor:stepCountType + unit:unit + predicate:predicate + ascending:ascending + limit:limit + completion:^(NSDictionary *results, NSError *error) { + if(results){ + callback(@[[NSNull null], results]); + return; + } else { + NSLog(@"error getting step samples by anchor : %@", error); + callback(@[RCTMakeError(@"error getting step samples by anchor", nil, nil)]); + return; + } + }]; +} - (void)fitness_getDailyStepSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback { diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Sleep.h b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Sleep.h index 3afd6d9f1a6c37a71b252dead5d0473782ba1a04..2ddbd5bf678288ec4173e7dbd86a9eb1412a2d71 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Sleep.h +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Sleep.h @@ -11,5 +11,6 @@ @interface RCTAppleHealthKit (Methods_Sleep) - (void)sleep_getSleepSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; +- (void)sleep_getSleepSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; @end diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Sleep.m b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Sleep.m index 4b1898f87aaa69f835290bcd9131ef9f1b3baf68..e28409762b53fee242d909c144fb37f4b10ca742 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Sleep.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Sleep.m @@ -43,5 +43,30 @@ } +- (void)sleep_getSleepSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback +{ + NSDate *startDate = [RCTAppleHealthKit dateFromOptions:input key:@"startDate" withDefault:nil]; + NSDate *endDate = [RCTAppleHealthKit dateFromOptions:input key:@"endDate" withDefault:[NSDate date]]; + if(startDate == nil){ + callback(@[RCTMakeError(@"startDate is required in options", nil, nil)]); + return; + } + + NSPredicate *predicate = [RCTAppleHealthKit predicateForSamplesBetweenDates:startDate endDate:endDate]; + NSUInteger limit = [RCTAppleHealthKit uintFromOptions:input key:@"limit" withDefault:HKObjectQueryNoLimit]; + + [self fetchSleepCategorySamplesForPredicateByAnchor:predicate + limit:limit + completion:^(NSDictionary *results, NSError *error) { + if(results){ + callback(@[[NSNull null], results]); + return; + } else { + NSLog(@"error getting sleep samples by anchor: %@", error); + callback(@[RCTMakeError(@"error getting sleep samples by anchor", nil, nil)]); + return; + } + }]; +} @end diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Vitals.h b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Vitals.h index db4df785fa4ec3819d2f03e6628c2e923f8209a8..20b913721abb472c5b92da2a9fa7db4fb348403b 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Vitals.h +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Vitals.h @@ -3,8 +3,10 @@ @interface RCTAppleHealthKit (Methods_Vitals) - (void)vitals_getHeartRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; +- (void)vitals_getHeartRateSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; - (void)vitals_getBodyTemperatureSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; - (void)vitals_getBloodPressureSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; +- (void)vitals_getBloodPressureSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; - (void)vitals_getRespiratoryRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback; @end diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Vitals.m b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Vitals.m index 500fafb1e66ff057ab3760c1563022a622ba606d..e93082b6599263185e3796284b1f41e16aef6279 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Vitals.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Methods_Vitals.m @@ -40,6 +40,40 @@ }]; } +- (void)vitals_getHeartRateSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback +{ + HKQuantityType *heartRateType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate]; + + HKUnit *count = [HKUnit countUnit]; + HKUnit *minute = [HKUnit minuteUnit]; + + HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[count unitDividedByUnit:minute]]; + NSUInteger limit = [RCTAppleHealthKit uintFromOptions:input key:@"limit" withDefault:HKObjectQueryNoLimit]; + BOOL ascending = [RCTAppleHealthKit boolFromOptions:input key:@"ascending" withDefault:false]; + NSDate *startDate = [RCTAppleHealthKit dateFromOptions:input key:@"startDate" withDefault:nil]; + NSDate *endDate = [RCTAppleHealthKit dateFromOptions:input key:@"endDate" withDefault:[NSDate date]]; + if(startDate == nil){ + callback(@[RCTMakeError(@"startDate is required in options", nil, nil)]); + return; + } + NSPredicate * predicate = [RCTAppleHealthKit predicateForSamplesBetweenDates:startDate endDate:endDate]; + + [self fetchQuantitySamplesOfTypeByAnchor:heartRateType + unit:unit + predicate:predicate + ascending:ascending + limit:limit + completion:^(NSDictionary *results, NSError *error) { + if(results){ + callback(@[[NSNull null], results]); + return; + } else { + NSLog(@"error getting heart rate samples: %@", error); + callback(@[RCTMakeError(@"error getting heart rate samples", nil, nil)]); + return; + } + }]; +} - (void)vitals_getBodyTemperatureSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback { @@ -156,6 +190,91 @@ }]; } +- (void)vitals_getBloodPressureSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback +{ + HKCorrelationType *bloodPressureCorrelationType = [HKCorrelationType correlationTypeForIdentifier:HKCorrelationTypeIdentifierBloodPressure]; + HKQuantityType *systolicType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodPressureSystolic]; + HKQuantityType *diastolicType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodPressureDiastolic]; + + HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[HKUnit millimeterOfMercuryUnit]]; + NSUInteger limit = [RCTAppleHealthKit uintFromOptions:input key:@"limit" withDefault:HKObjectQueryNoLimit]; + BOOL ascending = [RCTAppleHealthKit boolFromOptions:input key:@"ascending" withDefault:false]; + NSDate *startDate = [RCTAppleHealthKit dateFromOptions:input key:@"startDate" withDefault:nil]; + NSDate *endDate = [RCTAppleHealthKit dateFromOptions:input key:@"endDate" withDefault:[NSDate date]]; + if(startDate == nil){ + callback(@[RCTMakeError(@"startDate is required in options", nil, nil)]); + return; + } + NSPredicate * predicate = [RCTAppleHealthKit predicateForSamplesBetweenDates:startDate endDate:endDate]; + + [self fetchCorrelationSamplesOfTypeByAnchor:bloodPressureCorrelationType + unit:unit + predicate:predicate + ascending:ascending + limit:limit + completion:^(NSDictionary *results, NSError *error) { + if(results){ + NSMutableArray *data = [NSMutableArray arrayWithCapacity:1]; + + for (NSDictionary *sample in [results objectForKey:@"samples"]) { + HKCorrelation *bloodPressureValues = [sample valueForKey:@"correlation"]; + + HKQuantitySample *bloodPressureSystolicValue = [bloodPressureValues objectsForType:systolicType].anyObject; + HKQuantitySample *bloodPressureDiastolicValue = [bloodPressureValues objectsForType:diastolicType].anyObject; + + NSString *deviceName = bloodPressureSystolicValue.device.name ? bloodPressureSystolicValue.device.name : @""; + NSString *deviceManufacturer = bloodPressureSystolicValue.device.manufacturer ? bloodPressureSystolicValue.device.manufacturer : @""; + NSString *deviceHardwareVer = bloodPressureSystolicValue.device.hardwareVersion ? bloodPressureSystolicValue.device.hardwareVersion : @""; + NSString *deviceSoftwareVer = bloodPressureSystolicValue.device.softwareVersion ? bloodPressureSystolicValue.device.softwareVersion : @""; + + NSString *sourceName = bloodPressureSystolicValue.sourceRevision.source.name; + NSString *sourceId = bloodPressureSystolicValue.sourceRevision.source.bundleIdentifier; + + NSString *uuid = bloodPressureValues.UUID.UUIDString; + + NSError *error; + NSDictionary *metaDict; + if(bloodPressureSystolicValue.metadata == nil){ + metaDict = [[NSDictionary alloc] init]; + }else{ + metaDict = bloodPressureSystolicValue.metadata; + } + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:metaDict options:NSJSONWritingPrettyPrinted error:&error]; + NSString *metadata =[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + + NSDictionary *elem = @{ + @"bloodPressureSystolicValue" : @([bloodPressureSystolicValue.quantity doubleValueForUnit:unit]), + @"bloodPressureDiastolicValue" : @([bloodPressureDiastolicValue.quantity doubleValueForUnit:unit]), + @"startDate" : [sample valueForKey:@"startDate"], + @"endDate" : [sample valueForKey:@"endDate"], + @"deviceName" : deviceName, + @"deviceManufacturer" : deviceManufacturer, + @"deviceHardware" : deviceHardwareVer, + @"deviceSoftware" : deviceSoftwareVer, + @"sourceName" : sourceName, + @"sourceId" : sourceId, + @"unit" : unit.description, + @"uuid" : uuid, + @"metadata" : metadata + }; + + [data addObject:elem]; + } + + NSDictionary *result = @{ + @"samples" : data, + @"deleteSamples" : [results objectForKey:@"deleteSamples"] + }; + + callback(@[[NSNull null], result]); + return; + } else { + NSLog(@"error getting blood pressure samples by anchor: %@", error); + callback(@[RCTMakeError(@"error getting blood pressure samples by anchor", nil, nil)]); + return; + } + }]; +} - (void)vitals_getRespiratoryRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback { diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Queries.h b/RCTAppleHealthKit/RCTAppleHealthKit+Queries.h index 756f403a6e619234090230b5a92f83add14f8f82..4ff706ca5056528c99dfde6dcfff56c15fd99a87 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Queries.h +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Queries.h @@ -45,4 +45,22 @@ limit:(NSUInteger)lim completion:(void (^)(NSArray *, NSError *))completion; +- (void)fetchQuantitySamplesOfTypeByAnchor:(HKQuantityType *)quantityType + unit:(HKUnit *)unit + predicate:(NSPredicate *)predicate + ascending:(BOOL)asc + limit:(NSUInteger)lim + completion:(void (^)(NSDictionary *, NSError *))completion; + +- (void)fetchCorrelationSamplesOfTypeByAnchor:(HKQuantityType *)quantityType + unit:(HKUnit *)unit + predicate:(NSPredicate *)predicate + ascending:(BOOL)asc + limit:(NSUInteger)lim + completion:(void (^)(NSDictionary *, NSError *))completion; + +- (void)fetchSleepCategorySamplesForPredicateByAnchor:(NSPredicate *)predicate + limit:(NSUInteger)lim + completion:(void (^)(NSDictionary *, NSError *))completion; + @end diff --git a/RCTAppleHealthKit/RCTAppleHealthKit+Queries.m b/RCTAppleHealthKit/RCTAppleHealthKit+Queries.m index 01363730aad9604553ba7b25ef7849e6d0f0d263..6352072bba3356659d1223a4f19b8dc46d94d748 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit+Queries.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit+Queries.m @@ -498,4 +498,257 @@ [self.healthStore executeQuery:query]; } +- (void)fetchQuantitySamplesOfTypeByAnchor:(HKQuantityType *)quantityType + unit:(HKUnit *)unit + predicate:(NSPredicate *)predicate + ascending:(BOOL)asc + limit:(NSUInteger)lim + completion:(void (^)(NSDictionary *, NSError *))completion { + + void (^anchorHandlerBlock)(HKAnchoredObjectQuery *query, NSArray *sampleObjects, NSArray *deletedObjects, HKQueryAnchor *newAnchor, NSError *error); + anchorHandlerBlock = ^(HKAnchoredObjectQuery *query, NSArray *sampleObjects, NSArray *deletedObjects, HKQueryAnchor *newAnchor, NSError *error) { + if (!sampleObjects && !deletedObjects) { + if (completion) { + completion(nil, error); + } + return; + } + + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:newAnchor]; + [[NSUserDefaults standardUserDefaults] setObject:data forKey:quantityType.identifier]; + + if (completion) { + NSMutableArray *data = [NSMutableArray arrayWithCapacity:1]; + NSMutableArray *removeData = [NSMutableArray arrayWithCapacity:1]; + + dispatch_async(dispatch_get_main_queue(), ^{ + + for (HKQuantitySample *sample in sampleObjects) { + HKQuantity *quantity = sample.quantity; + double value = [quantity doubleValueForUnit:unit]; + + NSString *startDateString = [RCTAppleHealthKit buildISO8601StringFromDate:sample.startDate]; + NSString *endDateString = [RCTAppleHealthKit buildISO8601StringFromDate:sample.endDate]; + + NSString *deviceName = sample.device.name ? sample.device.name : @""; + NSString *deviceManufacturer = sample.device.manufacturer ? sample.device.manufacturer : @""; + NSString *deviceHardwareVer = sample.device.hardwareVersion ? sample.device.hardwareVersion : @""; + NSString *deviceSoftwareVer = sample.device.softwareVersion ? sample.device.softwareVersion : @""; + + NSString *sourceName = sample.sourceRevision.source.name; + NSString *sourceId = sample.sourceRevision.source.bundleIdentifier; + + NSString *uuid = sample.UUID.UUIDString; + + NSError *error; + NSDictionary *metaDict; + if(sample.metadata == nil){ + metaDict = [[NSDictionary alloc] init]; + }else{ + metaDict = sample.metadata; + } + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:metaDict options:NSJSONWritingPrettyPrinted error:&error]; + NSString *metadata =[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + + NSDictionary *elem = @{ + @"value" : @(value), + @"startDate" : startDateString, + @"endDate" : endDateString, + @"deviceName" : deviceName, + @"deviceManufacturer" : deviceManufacturer, + @"deviceHardware" : deviceHardwareVer, + @"deviceSoftware" : deviceSoftwareVer, + @"sourceName" : sourceName, + @"sourceId" : sourceId, + @"unit" : unit.description, + @"uuid" : uuid, + @"metadata" : metadata + }; + + [data addObject:elem]; + } + + for (HKDeletedObject *sample in deletedObjects) { + [removeData addObject:sample.UUID.UUIDString]; + } + + NSDictionary *result = @{ + @"samples" : data, + @"deleteSamples" : removeData + }; + + completion(result, error); + }); + } + }; + + NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:quantityType.identifier]; + HKQueryAnchor *anchor = [NSKeyedUnarchiver unarchiveObjectWithData:data]; + + HKAnchoredObjectQuery *anchorQuery = [[HKAnchoredObjectQuery alloc] initWithType:quantityType + predicate:predicate + anchor:anchor + limit:lim + resultsHandler:anchorHandlerBlock]; + [self.healthStore executeQuery:anchorQuery]; +} + +- (void)fetchCorrelationSamplesOfTypeByAnchor:(HKQuantityType *)quantityType + unit:(HKUnit *)unit + predicate:(NSPredicate *)predicate + ascending:(BOOL)asc + limit:(NSUInteger)lim + completion:(void (^)(NSDictionary *, NSError *))completion +{ + void (^anchorHandlerBlock)(HKAnchoredObjectQuery *query, NSArray *sampleObjects, NSArray *deletedObjects, HKQueryAnchor *newAnchor, NSError *error); + anchorHandlerBlock = ^(HKAnchoredObjectQuery *query, NSArray *sampleObjects, NSArray *deletedObjects, HKQueryAnchor *newAnchor, NSError *error) { + if (!sampleObjects && !deletedObjects) { + if (completion) { + completion(nil, error); + } + return; + } + + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:newAnchor]; + [[NSUserDefaults standardUserDefaults] setObject:data forKey:quantityType.identifier]; + + if (completion) { + NSMutableArray *data = [NSMutableArray arrayWithCapacity:1]; + NSMutableArray *removeData = [NSMutableArray arrayWithCapacity:1]; + + dispatch_async(dispatch_get_main_queue(), ^{ + + for (HKCorrelation *sample in sampleObjects) { + NSString *startDateString = [RCTAppleHealthKit buildISO8601StringFromDate:sample.startDate]; + NSString *endDateString = [RCTAppleHealthKit buildISO8601StringFromDate:sample.endDate]; + + NSDictionary *elem = @{ + @"correlation" : sample, + @"startDate" : startDateString, + @"endDate" : endDateString, + }; + [data addObject:elem]; + } + + for (HKDeletedObject *sample in deletedObjects) { + [removeData addObject:sample.UUID.UUIDString]; + } + + NSDictionary *result = @{ + @"samples" : data, + @"deleteSamples" : removeData + }; + + completion(result, error); + }); + } + }; + + NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:quantityType.identifier]; + HKQueryAnchor *anchor = [NSKeyedUnarchiver unarchiveObjectWithData:data]; + + HKAnchoredObjectQuery *anchorQuery = [[HKAnchoredObjectQuery alloc] initWithType:quantityType + predicate:predicate + anchor:anchor + limit:lim + resultsHandler:anchorHandlerBlock]; + + [self.healthStore executeQuery:anchorQuery]; +} + +- (void)fetchSleepCategorySamplesForPredicateByAnchor:(NSPredicate *)predicate + limit:(NSUInteger)lim + completion:(void (^)(NSDictionary *, NSError *))completion +{ + HKCategoryType *categoryType = [HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierSleepAnalysis]; + + void (^anchorHandlerBlock)(HKAnchoredObjectQuery *query, NSArray *sampleObjects, NSArray *deletedObjects, HKQueryAnchor *newAnchor, NSError *error); + anchorHandlerBlock = ^(HKAnchoredObjectQuery *query, NSArray *sampleObjects, NSArray *deletedObjects, HKQueryAnchor *newAnchor, NSError *error) { + if (!sampleObjects && !deletedObjects) { + if (completion) { + completion(nil, error); + } + return; + } + + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:newAnchor]; + [[NSUserDefaults standardUserDefaults] setObject:data forKey:categoryType.identifier]; + + if (completion) { + NSMutableArray *data = [NSMutableArray arrayWithCapacity:1]; + NSMutableArray *removeData = [NSMutableArray arrayWithCapacity:1]; + + dispatch_async(dispatch_get_main_queue(), ^{ + + for (HKCategorySample *sample in sampleObjects) { + NSInteger val = sample.value; + + NSString *startDateString = [RCTAppleHealthKit buildISO8601StringFromDate:sample.startDate]; + NSString *endDateString = [RCTAppleHealthKit buildISO8601StringFromDate:sample.endDate]; + + NSString *valueString = [NSString stringWithFormat:@"%d", val]; + + NSString *deviceName = sample.device.name ? sample.device.name : @""; + NSString *deviceManufacturer = sample.device.manufacturer ? sample.device.manufacturer : @""; + NSString *deviceHardwareVer = sample.device.hardwareVersion ? sample.device.hardwareVersion : @""; + NSString *deviceSoftwareVer = sample.device.softwareVersion ? sample.device.softwareVersion : @""; + + NSString *sourceName = sample.sourceRevision.source.name; + NSString *sourceId = sample.sourceRevision.source.bundleIdentifier; + + NSString *uuid = sample.UUID.UUIDString; + + NSError *error; + NSDictionary *metaDict; + if(sample.metadata == nil){ + metaDict = [[NSDictionary alloc] init]; + }else{ + metaDict = sample.metadata; + } + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:metaDict options:NSJSONWritingPrettyPrinted error:&error]; + NSString *metadata =[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + + NSDictionary *elem = @{ + @"value" : valueString, + @"startDate" : startDateString, + @"endDate" : endDateString, + @"deviceName" : deviceName, + @"deviceManufacturer" : deviceManufacturer, + @"deviceHardware" : deviceHardwareVer, + @"deviceSoftware" : deviceSoftwareVer, + @"sourceName" : sourceName, + @"sourceId" : sourceId, + @"uuid" : uuid, + @"metadata" : metadata + }; + + [data addObject:elem]; + } + + for (HKDeletedObject *sample in deletedObjects) { + [removeData addObject:sample.UUID.UUIDString]; + } + + NSDictionary *result = @{ + @"samples" : data, + @"deleteSamples" : removeData + }; + + completion(result, error); + }); + } + }; + + NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:categoryType.identifier]; + HKQueryAnchor *anchor = [NSKeyedUnarchiver unarchiveObjectWithData:data]; + + HKAnchoredObjectQuery *anchorQuery = [[HKAnchoredObjectQuery alloc] initWithType:categoryType + predicate:predicate + anchor:anchor + limit:lim + resultsHandler:anchorHandlerBlock]; + + [self.healthStore executeQuery:anchorQuery]; +} + @end diff --git a/RCTAppleHealthKit/RCTAppleHealthKit.m b/RCTAppleHealthKit/RCTAppleHealthKit.m index ba05b47c84e6ebb423024f42eb590ff8e2ce0b33..24ec62fbd80f155879208850f899eadb9dc28c20 100644 --- a/RCTAppleHealthKit/RCTAppleHealthKit.m +++ b/RCTAppleHealthKit/RCTAppleHealthKit.m @@ -110,6 +110,11 @@ RCT_EXPORT_METHOD(getStepCountSamples:(NSDictionary *)input callback:(RCTRespons [self fitness_geStepSamples:input callback:callback]; } +RCT_EXPORT_METHOD(getStepCountSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) +{ + [self fitness_geStepSamplesByAnchor:input callback:callback]; +} + RCT_EXPORT_METHOD(getDailyStepCountSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self fitness_getDailyStepSamples:input callback:callback]; @@ -140,6 +145,11 @@ RCT_EXPORT_METHOD(getHeartRateSamples:(NSDictionary *)input callback:(RCTRespons [self vitals_getHeartRateSamples:input callback:callback]; } +RCT_EXPORT_METHOD(getHeartRateSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) +{ + [self vitals_getHeartRateSamplesByAnchor:input callback:callback]; +} + RCT_EXPORT_METHOD(getBodyTemperatureSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self vitals_getBodyTemperatureSamples:input callback:callback]; @@ -150,6 +160,11 @@ RCT_EXPORT_METHOD(getBloodPressureSamples:(NSDictionary *)input callback:(RCTRes [self vitals_getBloodPressureSamples:input callback:callback]; } +RCT_EXPORT_METHOD(getBloodPressureSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) +{ + [self vitals_getBloodPressureSamplesByAnchor:input callback:callback]; +} + RCT_EXPORT_METHOD(getRespiratoryRateSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self vitals_getRespiratoryRateSamples:input callback:callback]; @@ -165,6 +180,11 @@ RCT_EXPORT_METHOD(getSleepSamples:(NSDictionary *)input callback:(RCTResponseSen [self sleep_getSleepSamples:input callback:callback]; } +RCT_EXPORT_METHOD(getSleepSamplesByAnchor:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) +{ + [self sleep_getSleepSamplesByAnchor:input callback:callback]; +} + RCT_EXPORT_METHOD(getInfo:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback) { [self getModuleInfo:input callback:callback];