forked from lucaspbordignon/rn-apple-healthkit
-
Notifications
You must be signed in to change notification settings - Fork 1
/
RCTAppleHealthKit+Methods_Body.m
298 lines (246 loc) · 12.6 KB
/
RCTAppleHealthKit+Methods_Body.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
//
// RCTAppleHealthKit+Methods_Body.m
// RCTAppleHealthKit
//
// Created by Greg Wilson on 2016-06-26.
// 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_Body.h"
#import "RCTAppleHealthKit+Queries.h"
#import "RCTAppleHealthKit+Utils.h"
@implementation RCTAppleHealthKit (Methods_Body)
- (void)body_getLatestWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKQuantityType *weightType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input];
if(unit == nil){
unit = [HKUnit poundUnit];
}
[self fetchMostRecentQuantitySampleOfType:weightType
predicate:nil
completion:^(HKQuantity *mostRecentQuantity, NSDate *startDate, NSDate *endDate, NSError *error) {
if (!mostRecentQuantity) {
NSLog(@"error getting latest weight: %@", error);
callback(@[RCTMakeError(@"error getting latest weight", error, nil)]);
}
else {
// Determine the weight in the required unit.
double usersWeight = [mostRecentQuantity doubleValueForUnit:unit];
NSDictionary *response = @{
@"value" : @(usersWeight),
@"startDate" : [RCTAppleHealthKit buildISO8601StringFromDate:startDate],
@"endDate" : [RCTAppleHealthKit buildISO8601StringFromDate:endDate],
};
callback(@[[NSNull null], response]);
}
}];
}
- (void)body_getWeightSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKQuantityType *weightType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[HKUnit poundUnit]];
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:weightType
unit:unit
predicate:predicate
ascending:ascending
limit:limit
completion:^(NSArray *results, NSError *error) {
if(results){
callback(@[[NSNull null], results]);
return;
} else {
NSLog(@"error getting weight samples: %@", error);
callback(@[RCTMakeError(@"error getting weight samples", nil, nil)]);
return;
}
}];
}
- (void)body_saveWeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
double weight = [RCTAppleHealthKit doubleValueFromOptions:input];
NSDate *sampleDate = [RCTAppleHealthKit dateFromOptionsDefaultNow:input];
HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input key:@"unit" withDefault:[HKUnit poundUnit]];
HKQuantity *weightQuantity = [HKQuantity quantityWithUnit:unit doubleValue:weight];
HKQuantityType *weightType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass];
HKQuantitySample *weightSample = [HKQuantitySample quantitySampleWithType:weightType quantity:weightQuantity startDate:sampleDate endDate:sampleDate];
[self.healthStore saveObject:weightSample withCompletion:^(BOOL success, NSError *error) {
if (!success) {
NSLog(@"error saving the weight sample: %@", error);
callback(@[RCTMakeError(@"error saving the weight sample", error, nil)]);
return;
}
callback(@[[NSNull null], @(weight)]);
}];
}
- (void)body_getLatestBodyMassIndex:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKQuantityType *bmiType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMassIndex];
[self fetchMostRecentQuantitySampleOfType:bmiType
predicate:nil
completion:^(HKQuantity *mostRecentQuantity, NSDate *startDate, NSDate *endDate, NSError *error) {
if (!mostRecentQuantity) {
NSLog(@"error getting latest BMI: %@", error);
callback(@[RCTMakeError(@"error getting latest BMI", error, nil)]);
}
else {
// Determine the bmi in the required unit.
HKUnit *countUnit = [HKUnit countUnit];
double bmi = [mostRecentQuantity doubleValueForUnit:countUnit];
NSDictionary *response = @{
@"value" : @(bmi),
@"startDate" : [RCTAppleHealthKit buildISO8601StringFromDate:startDate],
@"endDate" : [RCTAppleHealthKit buildISO8601StringFromDate:endDate],
};
callback(@[[NSNull null], response]);
}
}];
}
- (void)body_saveBodyMassIndex:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
double bmi = [RCTAppleHealthKit doubleValueFromOptions:input];
NSDate *sampleDate = [RCTAppleHealthKit dateFromOptionsDefaultNow:input];
HKUnit *unit = [HKUnit countUnit];
HKQuantity *bmiQuantity = [HKQuantity quantityWithUnit:unit doubleValue:bmi];
HKQuantityType *bmiType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMassIndex];
HKQuantitySample *bmiSample = [HKQuantitySample quantitySampleWithType:bmiType quantity:bmiQuantity startDate:sampleDate endDate:sampleDate];
[self.healthStore saveObject:bmiSample withCompletion:^(BOOL success, NSError *error) {
if (!success) {
NSLog(@"error saving BMI sample: %@.", error);
callback(@[RCTMakeError(@"error saving BMI sample", error, nil)]);
return;
}
callback(@[[NSNull null], @(bmi)]);
}];
}
- (void)body_getLatestHeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKQuantityType *heightType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight];
HKUnit *unit = [RCTAppleHealthKit hkUnitFromOptions:input];
if(unit == nil){
unit = [HKUnit inchUnit];
}
[self fetchMostRecentQuantitySampleOfType:heightType
predicate:nil
completion:^(HKQuantity *mostRecentQuantity, NSDate *startDate, NSDate *endDate, NSError *error) {
if (!mostRecentQuantity) {
NSLog(@"error getting latest height: %@", error);
callback(@[RCTMakeError(@"error getting latest height", error, nil)]);
}
else {
// Determine the height in the required unit.
double height = [mostRecentQuantity doubleValueForUnit:unit];
NSDictionary *response = @{
@"value" : @(height),
@"startDate" : [RCTAppleHealthKit buildISO8601StringFromDate:startDate],
@"endDate" : [RCTAppleHealthKit buildISO8601StringFromDate:endDate],
};
callback(@[[NSNull null], response]);
}
}];
}
- (void)body_getHeightSamples:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKQuantityType *heightType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight];
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:heightType
unit:unit
predicate:predicate
ascending:ascending
limit:limit
completion:^(NSArray *results, NSError *error) {
if(results){
callback(@[[NSNull null], results]);
return;
} else {
NSLog(@"error getting height samples: %@", error);
callback(@[RCTMakeError(@"error getting height samples", error, nil)]);
return;
}
}];
}
- (void)body_saveHeight:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
double height = [RCTAppleHealthKit doubleValueFromOptions:input];
NSDate *sampleDate = [RCTAppleHealthKit dateFromOptionsDefaultNow:input];
HKUnit *heightUnit = [RCTAppleHealthKit hkUnitFromOptions:input];
if(heightUnit == nil){
heightUnit = [HKUnit inchUnit];
}
HKQuantity *heightQuantity = [HKQuantity quantityWithUnit:heightUnit doubleValue:height];
HKQuantityType *heightType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight];
HKQuantitySample *heightSample = [HKQuantitySample quantitySampleWithType:heightType quantity:heightQuantity startDate:sampleDate endDate:sampleDate];
[self.healthStore saveObject:heightSample withCompletion:^(BOOL success, NSError *error) {
if (!success) {
NSLog(@"error saving height sample: %@", error);
callback(@[RCTMakeError(@"error saving height sample", error, nil)]);
return;
}
callback(@[[NSNull null], @(height)]);
}];
}
- (void)body_getLatestBodyFatPercentage:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKQuantityType *bodyFatPercentType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyFatPercentage];
[self fetchMostRecentQuantitySampleOfType:bodyFatPercentType
predicate:nil
completion:^(HKQuantity *mostRecentQuantity, NSDate *startDate, NSDate *endDate, NSError *error) {
if (!mostRecentQuantity) {
NSLog(@"error getting latest body fat percentage: %@", error);
callback(@[RCTMakeError(@"error getting latest body fat percentage", error, nil)]);
}
else {
// Determine the weight in the required unit.
HKUnit *percentUnit = [HKUnit percentUnit];
double percentage = [mostRecentQuantity doubleValueForUnit:percentUnit];
percentage = percentage * 100;
NSDictionary *response = @{
@"value" : @(percentage),
@"startDate" : [RCTAppleHealthKit buildISO8601StringFromDate:startDate],
@"endDate" : [RCTAppleHealthKit buildISO8601StringFromDate:endDate],
};
callback(@[[NSNull null], response]);
}
}];
}
- (void)body_getLatestLeanBodyMass:(NSDictionary *)input callback:(RCTResponseSenderBlock)callback
{
HKQuantityType *leanBodyMassType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierLeanBodyMass];
[self fetchMostRecentQuantitySampleOfType:leanBodyMassType
predicate:nil
completion:^(HKQuantity *mostRecentQuantity, NSDate *startDate, NSDate *endDate, NSError *error) {
if (!mostRecentQuantity) {
NSLog(@"error getting latest lean body mass: %@", error);
callback(@[RCTMakeError(@"error getting latest lean body mass", error, nil)]);
}
else {
HKUnit *weightUnit = [HKUnit poundUnit];
double leanBodyMass = [mostRecentQuantity doubleValueForUnit:weightUnit];
NSDictionary *response = @{
@"value" : @(leanBodyMass),
@"startDate" : [RCTAppleHealthKit buildISO8601StringFromDate:startDate],
@"endDate" : [RCTAppleHealthKit buildISO8601StringFromDate:endDate],
};
callback(@[[NSNull null], response]);
}
}];
}
@end