diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 6344dd8..6d509c0 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,6 +1,6 @@ PODS: - Expecta (1.0.5) - - Granola (0.3.0): + - Granola (0.4.0): - ObjectiveSugar (~> 1.1) - ObjectiveSugar (1.1.0) - Specta (1.0.5) @@ -18,7 +18,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Expecta: e1c022fcd33910b6be89c291d2775b3fe27a89fe - Granola: 9363048b8cc0309b43ed1f6b700af47b55b74f35 + Granola: c765790ab0a5ab322cb09717f415a1d12e0bdcb4 ObjectiveSugar: a6a25f23d657c19df0a0b972466d5b5ca9f5295c Specta: ac94d110b865115fe60ff2c6d7281053c6f8e8a2 VVJSONSchemaValidation: 11f5ba886e80baccae5d606f3b10f20c1303200d diff --git a/Example/Tests/OMHSampleFactory.m b/Example/Tests/OMHSampleFactory.m index 9f603e5..b615821 100644 --- a/Example/Tests/OMHSampleFactory.m +++ b/Example/Tests/OMHSampleFactory.m @@ -168,7 +168,8 @@ + (HKSample*)typeIdentifier:(NSString*)sampleTypeIdentifier HKQuantityTypeIdentifierBodyFatPercentage, HKQuantityTypeIdentifierRespiratoryRate, HKQuantityTypeIdentifierBodyTemperature, - HKQuantityTypeIdentifierBasalBodyTemperature + HKQuantityTypeIdentifierBasalBodyTemperature, + HKQuantityTypeIdentifierBloodAlcoholContent ] includes:sampleTypeIdentifier]) { NSString* defaultUnitString = nil; @@ -188,7 +189,8 @@ + (HKSample*)typeIdentifier:(NSString*)sampleTypeIdentifier defaultUnitString = @"mcg"; } else if (sampleTypeIdentifier == HKQuantityTypeIdentifierDietaryWater) { defaultUnitString = @"L"; - } else if (sampleTypeIdentifier == HKQuantityTypeIdentifierOxygenSaturation || sampleTypeIdentifier == HKQuantityTypeIdentifierBodyFatPercentage) { + } else if (sampleTypeIdentifier == HKQuantityTypeIdentifierOxygenSaturation || sampleTypeIdentifier == HKQuantityTypeIdentifierBodyFatPercentage + || sampleTypeIdentifier == HKQuantityTypeIdentifierBloodAlcoholContent) { defaultUnitString = @"%"; } else if (sampleTypeIdentifier == HKQuantityTypeIdentifierBodyTemperature || sampleTypeIdentifier == HKQuantityTypeIdentifierBasalBodyTemperature) { defaultUnitString = @"degC"; diff --git a/Example/Tests/OMHSerializerTests.m b/Example/Tests/OMHSerializerTests.m index 4b433cc..e7b8ad0 100644 --- a/Example/Tests/OMHSerializerTests.m +++ b/Example/Tests/OMHSerializerTests.m @@ -652,6 +652,32 @@ }); }); +describe(@"Generic quantity sample with percent unit", ^{ + itShouldBehaveLike(@"AnySerializerForSupportedSample",^{ + NSDate *start = [NSDate date]; + NSDate *end = start; + NSNumber *value = [NSNumber numberWithDouble:.127]; + NSString *unitString = @"%"; + HKSample *sample = [OMHSampleFactory typeIdentifier:HKQuantityTypeIdentifierBloodAlcoholContent + attrs:@{@"value":value, + @"unitString":unitString, + @"start":start, + @"end":end}]; + return @{ + @"sample":sample, + @"pathsToValues": @{ + @"header.schema_id.name": @"hk-quantity-sample", + @"header.schema_id.namespace":@"granola", + @"header.schema_id.version": @"1.0", + @"body.quantity_type":[HKQuantityTypeIdentifierBloodAlcoholContent description], + @"body.unit_value.value":@12.7, + @"body.unit_value.unit":@"%", + @"body.effective_time_frame.date_time":[start RFC3339String] + } + }; + }); +}); + describe(HKCorrelationTypeIdentifierFood,^{ itShouldBehaveLike(@"AnySerializerForSupportedSample", ^{ NSDate *sampleDate = [NSDate date]; @@ -1058,7 +1084,7 @@ describe(@"HKQuantityTypeIdentifierOxygenSaturation with time_interval", ^{ itShouldBehaveLike(@"AnySerializerForSupportedSample",^{ NSDate *start = [NSDate date]; - NSNumber *value = [NSNumber numberWithFloat:96.1]; + NSNumber *value = [NSNumber numberWithDouble:.961]; NSString *unitString = @"%"; HKSample *sample = [OMHSampleFactory typeIdentifier:HKQuantityTypeIdentifierOxygenSaturation attrs:@{@"value":value, @@ -1071,7 +1097,7 @@ @"header.schema_id.name": @"oxygen-saturation", @"header.schema_id.namespace":@"omh", @"header.schema_id.version": @"1.0", - @"body.oxygen_saturation.value":value, + @"body.oxygen_saturation.value":@96.1, @"body.oxygen_saturation.unit":unitString, @"body.effective_time_frame.date_time":[start RFC3339String] } @@ -1109,7 +1135,7 @@ itShouldBehaveLike(@"AnySerializerForSupportedSample",^{ NSDate *start = [NSDate date]; NSDate *end = [start dateByAddingTimeInterval:3600]; - NSNumber *value = [NSNumber numberWithFloat:23.2]; + NSNumber *value = [NSNumber numberWithDouble:.232]; NSString *unitString = @"%"; HKSample *sample = [OMHSampleFactory typeIdentifier:HKQuantityTypeIdentifierBodyFatPercentage attrs:@{@"value":value, @@ -1122,7 +1148,7 @@ @"header.schema_id.name": @"body-fat-percentage", @"header.schema_id.namespace":@"omh", @"header.schema_id.version": @"1.0", - @"body.body_fat_percentage.value": value, + @"body.body_fat_percentage.value": @23.2, @"body.body_fat_percentage.unit": unitString, @"body.effective_time_frame.time_interval.start_date_time": [sample.startDate RFC3339String], @"body.effective_time_frame.time_interval.end_date_time": [sample.endDate RFC3339String] diff --git a/Granola.podspec b/Granola.podspec index 5ac7bb8..7dd1d28 100644 --- a/Granola.podspec +++ b/Granola.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Granola" - s.version = "0.4.0" + s.version = "0.4.1" s.summary = "A healthful serializer for your HealthKit data." s.homepage = "https://github.com/openmhealth/Granola" s.license = { :type => 'Apache 2.0', diff --git a/Pod/Classes/OMHSerializer.m b/Pod/Classes/OMHSerializer.m index 062d029..b1f2ea3 100644 --- a/Pod/Classes/OMHSerializer.m +++ b/Pod/Classes/OMHSerializer.m @@ -430,11 +430,11 @@ + (BOOL)canSerialize:(HKQuantitySample*)sample error:(NSError**)error { - (id)bodyData { NSString* unitString = @"%"; HKUnit* unit = [HKUnit unitFromString:unitString]; - float value = [[(HKQuantitySample*)self.sample quantity] doubleValueForUnit:unit]; + double value = [[(HKQuantitySample*)self.sample quantity] doubleValueForUnit:unit]; return @{ @"oxygen_saturation": @{ - @"value": [NSNumber numberWithDouble:value], + @"value": [NSNumber numberWithDouble:value*100], @"unit": unitString }, @"effective_time_frame": [self populateTimeFrameProperty:self.sample.startDate endDate:self.sample.endDate] @@ -618,11 +618,10 @@ + (BOOL)canSerialize:(HKQuantitySample*)sample error:(NSError**)error { - (id)bodyData { NSString* unitString = @"%"; HKUnit* unit = [HKUnit unitFromString:unitString]; - float value = - [[(HKQuantitySample*)self.sample quantity] doubleValueForUnit:unit]; + double value = [[(HKQuantitySample*)self.sample quantity] doubleValueForUnit:unit]; return @{ @"body_fat_percentage": @{ - @"value": [NSNumber numberWithDouble:value], + @"value": [NSNumber numberWithDouble:value*100], @"unit": unitString }, @"effective_time_frame": [self populateTimeFrameProperty:self.sample.startDate endDate:self.sample.endDate] @@ -784,7 +783,21 @@ - (id)bodyData { HKQuantitySample *quantitySample = (HKQuantitySample*)self.sample; HKQuantity *quantity = [quantitySample quantity]; NSMutableDictionary *serializedUnitValues = [NSMutableDictionary new]; - if ([quantity isCompatibleWithUnit:[HKUnit unitFromString:@"count"]]) { + + if ([[OMHSerializer parseUnitFromQuantity:quantity] isEqualToString:@"%"]) { + + // Types that use "%" units are compatible with the "count" unit (in the next condition), so this condition to pre-empts that. + NSNumber* value = [NSNumber numberWithDouble:[quantity doubleValueForUnit:[HKUnit percentUnit]]]; + + [serializedUnitValues addEntriesFromDictionary:@{ + @"unit_value":@{ + @"value": @([value floatValue] * 100), + @"unit": @"%" + } + } + ]; + } + else if ([quantity isCompatibleWithUnit:[HKUnit unitFromString:@"count"]]) { [serializedUnitValues addEntriesFromDictionary:@{ @"count": [NSNumber numberWithDouble:[quantity doubleValueForUnit:[HKUnit unitFromString:@"count"]]] }