Skip to content

Commit

Permalink
Merge pull request #109 from kabaros/feature/waist-circumference
Browse files Browse the repository at this point in the history
Add support for waist circumference
  • Loading branch information
lucaspbordignon authored Jun 30, 2021
2 parents 22f44a7 + 05b1ea8 commit 8ec6586
Show file tree
Hide file tree
Showing 10 changed files with 229 additions and 0 deletions.
4 changes: 4 additions & 0 deletions RCTAppleHealthKit/RCTAppleHealthKit+Methods_Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
- (void)body_getHeightSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
- (void)body_saveHeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;

- (void)body_getLatestWaistCircumference:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
- (void)body_getWaistCircumferenceSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
- (void)body_saveWaistCircumference:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;

- (void)body_getLatestBodyFatPercentage:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
- (void)body_getBodyFatPercentageSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
- (void)body_saveBodyFatPercentage:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback;
Expand Down
79 changes: 79 additions & 0 deletions RCTAppleHealthKit/RCTAppleHealthKit+Methods_Body.m
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,85 @@ - (void)body_saveHeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)c
}];
}

- (void)body_getLatestWaistCircumference:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKQuantityType *waistCircumferenceType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierWaistCircumference];
HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[HKUnit inchUnit]];;

[self fetchMostRecentQuantitySampleOfType:waistCircumferenceType
predicate:nil
completion:^(HKQuantity *mostRecentQuantity, NSDate *startDate, NSDate *endDate, NSError *error) {
if (!mostRecentQuantity) {
NSLog(@"error getting latest waist circumference: %@", error);
callback(@[RCTMakeError(@"error getting latest wait circumference", error, nil)]);
}
else {
// Determine the waist circumference in the required unit.
double waistCircumference = [mostRecentQuantity doubleValueForUnit:unit];

NSDictionary *response = @{
@"value" : @(waistCircumference),
@"startDate" : [RCTAppleHealthKit buildISO8601StringFromDate:startDate],
@"endDate" : [RCTAppleHealthKit buildISO8601StringFromDate:endDate],
};

callback(@[[NSNull null], response]);
}
}];
}


- (void)body_getWaistCircumferenceSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKQuantityType *waistCircumferenceType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierWaistCircumference];

HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[HKUnit inchUnit]];
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 fetchQuantitySamplesOfType:waistCircumferenceType
unit:unit
predicate:predicate
ascending:ascending
limit:limit
completion:^(NSArray *results, NSError *error) {
if(results){
callback(@[[NSNull null], results]);
return;
} else {
callback(@[RCTJSErrorFromNSError(error)]);
return;
}
}];
}


- (void)body_saveWaistCircumference:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
double waistCircumference = [RCTAppleHealthKit doubleValueFromOptions:input];
NSDate *sampleDate = [RCTAppleHealthKit dateFromOptionsDefaultNow:input];
HKUnit *waistCircumferenceUnit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[HKUnit inchUnit]];

HKQuantity *waistCircumferenceQuantity = [HKQuantity quantityWithUnit:waistCircumferenceUnit doubleValue:waistCircumference];
HKQuantityType *waistCircumferenceType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierWaistCircumference];
HKQuantitySample *waistCircumferenceSample = [HKQuantitySample quantitySampleWithType:waistCircumferenceType quantity:waistCircumferenceQuantity startDate:sampleDate endDate:sampleDate];

[self.healthStore saveObject:waistCircumferenceSample withCompletion:^(BOOL success, NSError *error) {
if (!success) {
callback(@[RCTJSErrorFromNSError(error)]);
return;
}
callback(@[[NSNull null], @(waistCircumference)]);
}];
}


- (void)body_getLatestBodyFatPercentage:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
Expand Down
4 changes: 4 additions & 0 deletions RCTAppleHealthKit/RCTAppleHealthKit+TypesAndPermissions.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ - (nullable HKObjectType *)getReadPermFromText:(nonnull NSString*)key {
return [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierBiologicalSex];
} else if ([@"BloodType" isEqualToString: key]) {
return [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierBloodType];
} else if ([@"WaistCircumference" isEqualToString: key] && systemVersion >= 11.0) {
return [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierWaistCircumference];
}

// Body Measurements
Expand Down Expand Up @@ -195,6 +197,8 @@ - (nullable HKObjectType *)getWritePermFromText:(nonnull NSString*) key {
// Body Measurements
if ([@"Height" isEqualToString:key]) {
return [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight];
} else if ([@"WaistCircumference" isEqualToString:key]) {
return [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierWaistCircumference];
} else if ([@"Weight" isEqualToString:key]) {
return [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
} else if ([@"BodyMass" isEqualToString:key]) {
Expand Down
18 changes: 18 additions & 0 deletions RCTAppleHealthKit/RCTAppleHealthKit.m
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,24 @@ @implementation RCTAppleHealthKit
[self body_saveHeight:input callback:callback];
}

RCT_EXPORT_METHOD(getLatestWaistCircumference:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self _initializeHealthStore];
[self body_getLatestWaistCircumference:input callback:callback];
}

RCT_EXPORT_METHOD(getWaistCircumferenceSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self _initializeHealthStore];
[self body_getWaistCircumferenceSamples:input callback:callback];
}

RCT_EXPORT_METHOD(saveWaistCircumference:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self _initializeHealthStore];
[self body_saveWaistCircumference:input callback:callback];
}

RCT_EXPORT_METHOD(getLatestBmi:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback)
{
[self _initializeHealthStore];
Expand Down
3 changes: 3 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,17 @@ There is a gitbook version for the documentation on this [link](https://vinicius

- [getLatestHeight](getLatestHeight.md)
- [getLatestWeight](getLatestWeight.md)
- [getLatestWaistCircumference](getLatestWaistCircumference.md)
- [getHeightSamples](getHeightSamples.md)
- [getWaistCircumferenceSamples](getWaistCircumferenceSamples.md)
- [getWeightSamples](getWeightSamples.md)
- [getBodyTemperatureSamples](getBodyTemperatureSamples.md)
- [getLatestBodyFatPercentage](getLatestBodyFatPercentage.md)
- [getBodyFatPercentageSamples](getBodyFatPercentageSamples.md)
- [getLatestLeanBodyMass](getLatestLeanBodyMass.md)
- [getLeanBodyMassSamples](getLeanBodyMassSamples.md)
- [saveHeight](saveHeight.md)
- [saveWaistCircumference](saveWaistCircumference.md)
- [saveWeight](saveWeight.md)
- [saveBodyFatPercentage](saveBodyFatPercentage.md)
- [saveBodyTemperature](/docs/saveBodyTemperature.md)
Expand Down
25 changes: 25 additions & 0 deletions docs/getLatestWaistCircumference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# getLatestWaistCircumference

Get the most recent waist circumference value. Waist circumference is available in iOS 11.0+.

On success, the callback function will be provided with a `waistCircumference` object containing the waist circumference `value`, and the `startDate` and `endDate` of the waist circumference sample. _Note: startDate and endDate will be the same as waist circumference samples are saved at a specific point in time._

```javascript
AppleHealthKit.getLatestWaistCircumference({}, (err: string, results: HealthValue) => {
if (err) {
console.log('error getting latest waist circumference: ', err)
return
}
console.log(results)
})
```

Example output:

```json
{
"value": 39,
"startDate": "2021-06-15T11:08:05.366+0100",
"endDate": "2021-06-15T11:08:05.366+0100"
}
```
46 changes: 46 additions & 0 deletions docs/getWaistCircumferenceSamples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# getWaistCircumferenceSamples

Query for waist circumference samples. The options object is used to setup a query to retrieve relevant samples. Waist circumference is available in iOS 11.0+.

Example input options:

```javascript
let options = {
unit: 'inch', // optional; default 'inch'
startDate: new Date(2021, 0, 0).toISOString(), // required
endDate: new Date().toISOString(), // optional; default now
ascending: false, // optional; default false
limit: 10, // optional; default no limit
}
```

Call the method:

```javascript
AppleHealthKit.getWaistCircumferenceSamples(
options,
(err: Object, results: Array<HealthValue>) => {
if (err) {
return
}
console.log(results)
},
)
```

Example output:

```json
[
{
"value": 39.02,
"startDate": "2016-06-29T17:55:00.000-0400",
"endDate": "2016-06-29T17:55:00.000-0400"
},
{
"value": 39,
"startDate": "2016-03-12T13:22:00.000-0400",
"endDate": "2016-03-12T13:22:00.000-0400"
}
]
```
33 changes: 33 additions & 0 deletions docs/saveWaistCircumference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# saveWaistCircumference

save a numeric waist circumference value to Healthkit. Waist circumference is available in iOS 11.0+.

`saveWaistCircumference` accepts an options object containing a numeric waist circumference value:

Example input options:

```javascript
let options = {
value: 39, // Inches
}
```

Call the method:

```javascript
AppleHealthKit.saveWaistCircumference(
(options: HealthValueOptions),
(err: Object, results: number) => {
if (err) {
return
}
// waist circumference successfully saved
},
)
```

Example output:

```json
39
```
16 changes: 16 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,21 @@ declare module 'react-native-health' {
options: HealthValueOptions,
callback: (error: string, result: HealthValue) => void,
): void

getLatestWaistCircumference(
options: HealthUnitOptions,
callback: (err: string, results: HealthValue) => void,
): void

getWaistCircumferenceSamples(
options: HealthInputOptions,
callback: (err: string, results: Array<HealthValue>) => void,
): void

saveWaistCircumference(
options: HealthValueOptions,
callback: (error: string, result: HealthValue) => void,
): void

saveLeanBodyMass(
options: HealthValueOptions,
Expand Down Expand Up @@ -560,6 +575,7 @@ declare module 'react-native-health' {
Vo2Max = 'Vo2Max',
Weight = 'Weight',
Workout = 'Workout',
WaistCircumference = 'WaistCircumference'
}

export enum HealthUnit {
Expand Down
1 change: 1 addition & 0 deletions src/constants/Permissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export const Permissions = {
StepCount: 'StepCount',
Steps: 'Steps',
Vo2Max: 'Vo2Max',
WaistCircumference: 'WaistCircumference',
Weight: 'Weight',
Workout: 'Workout',
}

0 comments on commit 8ec6586

Please sign in to comment.