Skip to content

Commit

Permalink
Merge pull request ResearchKit#129 from syoung-smallwisdom/lux-changes
Browse files Browse the repository at this point in the history
Allow weight and height to use metric units.
  • Loading branch information
Erin-Mounts committed Jun 7, 2016
2 parents 4905faa + 6c1307c commit a8f7670
Show file tree
Hide file tree
Showing 12 changed files with 381 additions and 213 deletions.
8 changes: 8 additions & 0 deletions APCAppCore/APCAppCore.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,8 @@
FB4E468C1C7E6E0000CADC1F /* APCNavigationFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = FB4E468A1C7E6E0000CADC1F /* APCNavigationFooter.m */; };
FBAE3D5E1C878064003CEC4A /* APCOptionalStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = FBAE3D5C1C878064003CEC4A /* APCOptionalStepViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
FBAE3D5F1C878064003CEC4A /* APCOptionalStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FBAE3D5D1C878064003CEC4A /* APCOptionalStepViewController.m */; };
FF00961B1D05F23D006258B5 /* APCPickerItemQuantity.h in Headers */ = {isa = PBXBuildFile; fileRef = FF0096191D05F23D006258B5 /* APCPickerItemQuantity.h */; };
FF00961C1D05F23D006258B5 /* APCPickerItemQuantity.m in Sources */ = {isa = PBXBuildFile; fileRef = FF00961A1D05F23D006258B5 /* APCPickerItemQuantity.m */; };
FF0B4A961C29D98C00224EF7 /* APCScene.h in Headers */ = {isa = PBXBuildFile; fileRef = FF0B4A941C29D98C00224EF7 /* APCScene.h */; settings = {ATTRIBUTES = (Public, ); }; };
FF0B4A971C29D98C00224EF7 /* APCScene.m in Sources */ = {isa = PBXBuildFile; fileRef = FF0B4A951C29D98C00224EF7 /* APCScene.m */; };
FF44E50A1C1A3BB200F07DA9 /* BridgeSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FF44E5091C1A3BB200F07DA9 /* BridgeSDK.framework */; };
Expand Down Expand Up @@ -1483,6 +1485,8 @@
FB4E468A1C7E6E0000CADC1F /* APCNavigationFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = APCNavigationFooter.m; sourceTree = "<group>"; };
FBAE3D5C1C878064003CEC4A /* APCOptionalStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APCOptionalStepViewController.h; sourceTree = "<group>"; };
FBAE3D5D1C878064003CEC4A /* APCOptionalStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = APCOptionalStepViewController.m; sourceTree = "<group>"; };
FF0096191D05F23D006258B5 /* APCPickerItemQuantity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APCPickerItemQuantity.h; sourceTree = "<group>"; };
FF00961A1D05F23D006258B5 /* APCPickerItemQuantity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = APCPickerItemQuantity.m; sourceTree = "<group>"; };
FF0B4A941C29D98C00224EF7 /* APCScene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APCScene.h; sourceTree = "<group>"; };
FF0B4A951C29D98C00224EF7 /* APCScene.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = APCScene.m; sourceTree = "<group>"; };
FF44E5091C1A3BB200F07DA9 /* BridgeSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BridgeSDK.framework; path = "../../../../../Library/Developer/Xcode/DerivedData/Parkinson-dphbgsbdqdzhcbeketqhdiecbfyz/Build/Products/Debug-iphoneos/BridgeSDK.framework"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2739,6 +2743,8 @@
5B04329E1A318AA2000DC9ED /* APCSignInTask.m */,
F5F129411A2F78490015982C /* APCTableViewItem.h */,
F5F129421A2F78490015982C /* APCTableViewItem.m */,
FF0096191D05F23D006258B5 /* APCPickerItemQuantity.h */,
FF00961A1D05F23D006258B5 /* APCPickerItemQuantity.m */,
);
path = Model;
sourceTree = "<group>";
Expand Down Expand Up @@ -3261,6 +3267,7 @@
5B9B36A71A95D9C900389F42 /* APCActivitiesBasicTableViewCell.h in Headers */,
3650C65B1AA29BB50075C935 /* APCCatastrophicErrorViewController.h in Headers */,
7B751D571B0A61A600E77BD2 /* NSDictionary+APCStringify.h in Headers */,
FF00961B1D05F23D006258B5 /* APCPickerItemQuantity.h in Headers */,
F5B9480C1A73272C0034C522 /* APCScheduleExpressionTokenizer.h in Headers */,
F5F12A851A2F78490015982C /* APCOnboarding.h in Headers */,
369E27F31A96B7A200D35DFA /* APCMedicationLozenge.h in Headers */,
Expand Down Expand Up @@ -3665,6 +3672,7 @@
F5F12AE11A2F78490015982C /* APCSwitchTableViewCell.m in Sources */,
F5B946351A7309A20034C522 /* ZZError.m in Sources */,
5BE106F11A9EE2D900CA5A07 /* APCDashboardGraphTableViewCell.m in Sources */,
FF00961C1D05F23D006258B5 /* APCPickerItemQuantity.m in Sources */,
CFFDEDF31A95734000B25581 /* APCMedicationSummaryTableViewCell.m in Sources */,
7B8DBEC51AA1871D007B4026 /* APCVerticalThinLineView.m in Sources */,
5B0432A01A318AA2000DC9ED /* APCSignInTask.m in Sources */,
Expand Down
11 changes: 8 additions & 3 deletions APCAppCore/APCAppCore/DataSubstrate/Model/APCUser+UserData.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@

#import "APCUser.h"

@class APCPickerItemQuantity;

@interface APCUser (UserData)

/* Biologcal Sex */
Expand All @@ -58,9 +60,8 @@
+ (NSArray *) medications;

/* Height */
+ (NSArray *) heights;

+ (double)heightInInchesForSelectedIndices:(NSArray *)selectedIndices;
+ (NSArray *) heights __attribute__((deprecated("Please use -localizedHeightPickerDataAndSelectedIndices:")));
+ (double)heightInInchesForSelectedIndices:(NSArray *)selectedIndices __attribute__((deprecated("Please use -setHeightForPickerData:selectedIndices:")));

+ (double)heightInInches:(HKQuantity *)height;

Expand All @@ -71,4 +72,8 @@

+ (double)weightInKilograms:(HKQuantity *)weight;

- (NSArray <APCPickerItemQuantity *> *)localizedHeightPickerDataAndSelectedIndices:(NSArray <NSNumber *> **)selectedIndices;
- (void)setHeightForPickerData:(NSArray *)pickerData selectedIndices:(NSArray *)selectedIndices;


@end
86 changes: 86 additions & 0 deletions APCAppCore/APCAppCore/DataSubstrate/Model/APCUser+UserData.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

#import "APCUser+UserData.h"
#import "APCLocalization.h"
#import "APCPickerItemQuantity.h"

@implementation APCUser (UserData)

Expand Down Expand Up @@ -127,6 +128,91 @@ + (NSArray *) medications {
/*******
Height
*******/

- (NSArray <APCPickerItemQuantity *> *)localizedHeightPickerDataAndSelectedIndices:(NSArray <NSNumber *> **)selectedIndices
{
// Find the appropriate localized unit
NSLengthFormatterUnit formatterUnit;
NSLengthFormatter *formatter = [[NSLengthFormatter alloc] init];
formatter.unitStyle = NSFormattingUnitStyleMedium;
formatter.forPersonHeightUse = YES;
[formatter unitStringFromMeters:2.0 usedUnit:&formatterUnit];

// Convert the formatter unit to a HKUnit (default to centimeter)
NSArray *hkUnits = @[[HKUnit meterUnitWithMetricPrefix:HKMetricPrefixCenti]];
NSArray *formatterUnits = @[@(NSLengthFormatterUnitCentimeter)];
NSArray *maxValues = @[@(floor((8 * 12 + 11) * 2.54))];
NSArray *builderUnits = hkUnits;

switch (formatterUnit) {
case NSLengthFormatterUnitInch:
case NSLengthFormatterUnitFoot:
case NSLengthFormatterUnitYard:
hkUnits = @[[HKUnit footUnit], [HKUnit inchUnit]];
formatterUnits = @[@(NSLengthFormatterUnitFoot), @(NSLengthFormatterUnitInch)];
maxValues = @[@(8), @(11)];
builderUnits = hkUnits;
formatter.unitStyle = NSFormattingUnitStyleShort;
break;

case NSLengthFormatterUnitCentimeter:
break;

default:
hkUnits = @[[HKUnit meterUnit]];
formatterUnits = @[@(NSLengthFormatterUnitMeter)];
break;
}

NSMutableArray *heights = [NSMutableArray new];
NSMutableArray *currentIndices = self.height != nil ? [NSMutableArray new] : nil;

for (NSUInteger ii=0; ii < maxValues.count; ii++) {

NSMutableArray *columnData = [NSMutableArray new];
NSUInteger maxValue = [maxValues[ii] unsignedIntegerValue];
HKUnit *builderUnit = builderUnits[ii];
double height = [self.height doubleValueForUnit:builderUnit];
for (NSUInteger jj=0; jj < ii; jj++) {
HKQuantity *unitQuantity = [HKQuantity quantityWithUnit:builderUnits[jj] doubleValue:1.0];
height -= [currentIndices[jj] doubleValue] * [unitQuantity doubleValueForUnit:builderUnit];
}
BOOL isLast = (ii == maxValues.count - 1);
NSUInteger current = MIN(maxValue, isLast ? round(height) : floor(height));
[currentIndices addObject:@(current)];

for (NSUInteger nn=0; nn <= maxValue; nn++) {
HKQuantity *quantity = [HKQuantity quantityWithUnit:builderUnit doubleValue:(double)nn];
double value = [quantity doubleValueForUnit:hkUnits[ii]];
NSString *text = [formatter stringFromValue:value unit:[formatterUnits[ii] integerValue]];
APCPickerItemQuantity *pickerData = [[APCPickerItemQuantity alloc] initWithQuantity:quantity text:text];
[columnData addObject:pickerData];
}

[heights addObject:[columnData copy]];
}

if (currentIndices != nil && selectedIndices != nil) {
*selectedIndices = [currentIndices copy];
}

return [heights copy];
}

- (void)setHeightForPickerData:(NSArray *)pickerData selectedIndices:(NSArray *)selectedIndices {
double value = 0;
HKUnit *unit = [HKUnit meterUnit];
for (NSInteger ii=selectedIndices.count - 1; ii >= 0; ii--) {
NSUInteger idx = [selectedIndices[ii] unsignedIntegerValue];
NSArray *columnData = pickerData[ii];
APCPickerItemQuantity *item = columnData[idx];
value += [item.quantity doubleValueForUnit:unit];
}
if (value > 0) {
self.height = [HKQuantity quantityWithUnit:unit doubleValue:value];
}
}

+ (NSArray *) heights {
return @[
@[@"0'", @"1'", @"2'", @"3'", @"4'", @"5'", @"6'", @"7'", @"8'"],
Expand Down
49 changes: 49 additions & 0 deletions APCAppCore/APCAppCore/UI/Model/APCPickerItemQuantity.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// APCPickerItemQuantity.h
// APCAppCore
//
// Copyright © 2016 Sage Bionetworks. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation and/or
// other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder(s) nor the names of any contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission. No license is granted to the trademarks of
// the copyright holders even if such marks are included in this software.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//


#import <Foundation/Foundation.h>
#import <HealthKit/HealthKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface APCPickerItemQuantity : NSObject <NSCopying>

@property (nonatomic, readonly) HKQuantity *quantity;
@property (nonatomic, readonly) NSString *text;

- (instancetype)initWithQuantity:(HKQuantity *)quantity text:(NSString *)text NS_DESIGNATED_INITIALIZER;

@end

NS_ASSUME_NONNULL_END
63 changes: 63 additions & 0 deletions APCAppCore/APCAppCore/UI/Model/APCPickerItemQuantity.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// APCPickerItemQuantity.m
// APCAppCore
//
// Copyright © 2016 Sage Bionetworks. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation and/or
// other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder(s) nor the names of any contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission. No license is granted to the trademarks of
// the copyright holders even if such marks are included in this software.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//


#import "APCPickerItemQuantity.h"

@implementation APCPickerItemQuantity

- (instancetype)initWithQuantity:(HKQuantity *)quantity text:(NSString *)text {
if (self = [super init]) {
_quantity = quantity;
_text = text;
}
return self;
}

- (NSString *)description {
return self.text;
}

- (id)copyWithZone:(NSZone *)zone {
return [[[self class] allocWithZone:zone] initWithQuantity:self.quantity text:self.text];
}

- (NSUInteger)hash {
return self.quantity.hash;
}

- (BOOL)isEqual:(id)object {
return [object isMemberOfClass:[self class]] && [self.quantity isEqual:[object quantity]];
}

@end
4 changes: 4 additions & 0 deletions APCAppCore/APCAppCore/UI/Model/APCTableViewItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@

@property (nonatomic, copy) NSString *value;

@property (nonatomic, copy) HKUnit *unit;

- (HKQuantity *)quantity;

@end


Expand Down
2 changes: 1 addition & 1 deletion APCAppCore/APCAppCore/UI/Model/APCTableViewItem.m
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ - (NSString *) stringValue {

NSInteger selectedRowInComponent = [self.selectedRowIndices[i] integerValue];

[string appendString:component[selectedRowInComponent]];
[string appendString:[component[selectedRowInComponent] description]];

if (i < (self.pickerData.count - 1)) {
[string appendString:@" "];
Expand Down
Loading

0 comments on commit a8f7670

Please sign in to comment.