Compare commits

...

6 Commits

Author SHA1 Message Date
Akshay 44c88877c5 Fix for CocoaPods 2017-07-13 11:42:25 -07:00
Akshay 6f2ac3f671 Fixes 2017-07-13 11:19:33 -07:00
Akshay 007583929c Convergence 2017-07-06 18:08:13 -07:00
Akshay c97d6bd78c Convergence 2017-07-06 15:33:24 -07:00
Umer Khan 6089b09963 Merge pull request #853 from ryanschneider/podspec-fix
Fix typo in podspec version quoting characters.
2016-10-27 14:42:33 -07:00
Ryan Schneider 87a7a6a718 Fix typo in podspec version quoting characters. 2016-10-27 11:26:15 -07:00
425 changed files with 16400 additions and 2123 deletions
+8 -8
View File
@@ -214,14 +214,14 @@ This has just one required method, which you must implement in order to handle t
*Swift*
```swift
func taskViewController(taskViewController: ORKTaskViewController,
didFinishWithReason reason: ORKTaskViewControllerFinishReason,
error: NSError?) {
let taskResult = taskViewController.result
// You could do something with the result here.
func taskViewController(_ taskViewController: ORKTaskViewController,
didFinishWith reason: ORKTaskViewControllerFinishReason,
error: Error?) {
let taskResult = taskViewController.result
// You could do something with the result here.
// Then, dismiss the task view controller.
dismissViewControllerAnimated(true, completion: nil)
// Then, dismiss the task view controller.
dismiss(true, completion: nil)
}
```
@@ -253,7 +253,7 @@ The source in the *ResearchKit* repository is made available under the following
another license is explicitly identified:
```
Copyright (c) 2015, Apple Inc. All rights reserved.
Copyright (c) 2015 - 2017, Apple Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
+59
View File
@@ -1,5 +1,64 @@
# ResearchKit Release Notes
## ResearchKit 1.5 Release Notes
*ResearchKit 1.5* supports *iOS* and requires *Xcode 8.0* or newer. The minimum supported *Base SDK* is *8.0*.
In addition to general stabiltiy and performance improvements, *ResearchKit 1.5* includes the following new features and enhancements.
- **New Active Tasks**
- **Stroop Test**
*Contributed by [Apple Inc](https://github.com/researchkit).*
The *Stroop Test* shows the participant different combinations of text and tint colors on the screen.
Users must ignore the text and instead select the button that reflects the first letter of the tint color.
- **Trail Making Test**
*Contributed by Faraz Hussain.*
The *Trail Making Test* instructs participants to connect a series of labelled circles and the time to complete the test is recorded.
- **Range of Motion Test**
*Contributed by Daren Levy, Dr. Raj Karia, John Guydo.*
Participants are instructed to follow a series of steps while accelerometer and gyroscope data is captured to measure flexed and extended positions for both the shoulder and knee.
- **Touch Anywhere Active Task**
*Contributed by Daren Levy, Dr. Raj Karia, John Guydo*
Allows the user to get their device in the proper position and then tap the screen to indicate they are ready to begin the next step.
- **New Steps**
- **Video Instruction Step**
*Contributed by [Oliver Schäfer](https://github.com/oliverschaefer).*
The *Video Instruction Step* provides a step to be used to display a video.
This step can be used to display videos to users from either a local or remote source.
- **Other Improvements**
- **Tone Audiometry Test**
*Contributed by [Apple Inc](https://github.com/researchkit).*
Updated to include both a left and right button.
- **Digital Object Identifier**
*Contributed by [Apple Inc](https://github.com/researchkit).*
Assigns a Digital Object Identifier to the ResearchKit repository on GitHub to use when referencing the framework.
## ResearchKit 1.4 Release Notes
*ResearchKit 1.4* supports *iOS* and requires *Xcode 8.0* or newer. The minimum supported *Base SDK* is *8.0*.
+2 -2
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'ResearchKit'
s.version = 1.4.1
s.version = '1.5.2'
s.summary = 'ResearchKit is an open source software framework that makes it easy to create apps for medical research or for other research projects.'
s.homepage = 'https://www.github.com/ResearchKit/ResearchKit'
s.documentation_url = 'http://researchkit.github.io/docs/'
@@ -10,6 +10,6 @@ Pod::Spec.new do |s|
s.public_header_files = `./scripts/find_headers.rb --public --private`.split("\n")
s.source_files = 'ResearchKit/**/*.{h,m,swift}'
s.resources = 'ResearchKit/**/*.{fsh,vsh}', 'ResearchKit/Animations/**/*.m4v', 'ResearchKit/Artwork.xcassets', 'ResearchKit/Localized/*.lproj'
s.platform = :ios, '8.0'
s.platform = :ios, '8.2'
s.requires_arc = true
end
+257 -21
View File
@@ -126,6 +126,12 @@
618DA0521A93D0D600E63AA8 /* ORKAccessibilityFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 618DA04A1A93D0D600E63AA8 /* ORKAccessibilityFunctions.m */; };
618DA0541A93D0D600E63AA8 /* UIView+ORKAccessibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 618DA04B1A93D0D600E63AA8 /* UIView+ORKAccessibility.h */; };
618DA0561A93D0D600E63AA8 /* UIView+ORKAccessibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 618DA04C1A93D0D600E63AA8 /* UIView+ORKAccessibility.m */; };
781D54101DF886AB00223305 /* ORKTrailmakingContentView.h in Headers */ = {isa = PBXBuildFile; fileRef = 781D540A1DF886AB00223305 /* ORKTrailmakingContentView.h */; };
781D54111DF886AB00223305 /* ORKTrailmakingContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 781D540B1DF886AB00223305 /* ORKTrailmakingContentView.m */; };
781D54121DF886AB00223305 /* ORKTrailmakingStep.h in Headers */ = {isa = PBXBuildFile; fileRef = 781D540C1DF886AB00223305 /* ORKTrailmakingStep.h */; settings = {ATTRIBUTES = (Private, ); }; };
781D54131DF886AB00223305 /* ORKTrailmakingStep.m in Sources */ = {isa = PBXBuildFile; fileRef = 781D540D1DF886AB00223305 /* ORKTrailmakingStep.m */; };
781D54141DF886AB00223305 /* ORKTrailmakingStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 781D540E1DF886AB00223305 /* ORKTrailmakingStepViewController.h */; };
781D54151DF886AB00223305 /* ORKTrailmakingStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 781D540F1DF886AB00223305 /* ORKTrailmakingStepViewController.m */; };
805685791C90C19500BF437A /* UIImage+ResearchKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 805685771C90C19500BF437A /* UIImage+ResearchKit.h */; };
8056857A1C90C19500BF437A /* UIImage+ResearchKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 805685781C90C19500BF437A /* UIImage+ResearchKit.m */; };
861D11A91AA691BB003C98A7 /* ORKScaleSliderView.h in Headers */ = {isa = PBXBuildFile; fileRef = 861D11A71AA691BB003C98A7 /* ORKScaleSliderView.h */; };
@@ -433,6 +439,18 @@
86CC8EBA1AC09383001CCD89 /* ORKResultTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 86CC8EAF1AC09383001CCD89 /* ORKResultTests.m */; };
86CC8EBB1AC09383001CCD89 /* ORKTextChoiceCellGroupTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 86CC8EB01AC09383001CCD89 /* ORKTextChoiceCellGroupTests.m */; };
86D348021AC161B0006DB02B /* ORKRecorderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 86D348001AC16175006DB02B /* ORKRecorderTests.m */; };
9550E6731D58DBCF00C691B8 /* ORKTouchAnywhereStep.h in Headers */ = {isa = PBXBuildFile; fileRef = 9550E6711D58DBCF00C691B8 /* ORKTouchAnywhereStep.h */; settings = {ATTRIBUTES = (Public, ); }; };
9550E6741D58DBCF00C691B8 /* ORKTouchAnywhereStep.m in Sources */ = {isa = PBXBuildFile; fileRef = 9550E6721D58DBCF00C691B8 /* ORKTouchAnywhereStep.m */; };
9550E67C1D58DD2000C691B8 /* ORKTouchAnywhereStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 9550E67A1D58DD2000C691B8 /* ORKTouchAnywhereStepViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
9550E67D1D58DD2000C691B8 /* ORKTouchAnywhereStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9550E67B1D58DD2000C691B8 /* ORKTouchAnywhereStepViewController.m */; };
959A2BFC1D68B98700841B04 /* ORKRangeOfMotionStep.h in Headers */ = {isa = PBXBuildFile; fileRef = 959A2BFA1D68B98700841B04 /* ORKRangeOfMotionStep.h */; settings = {ATTRIBUTES = (Private, ); }; };
959A2BFD1D68B98700841B04 /* ORKRangeOfMotionStep.m in Sources */ = {isa = PBXBuildFile; fileRef = 959A2BFB1D68B98700841B04 /* ORKRangeOfMotionStep.m */; };
959A2C001D68B9DA00841B04 /* ORKRangeOfMotionStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 959A2BFE1D68B9DA00841B04 /* ORKRangeOfMotionStepViewController.h */; };
959A2C011D68B9DA00841B04 /* ORKRangeOfMotionStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 959A2BFF1D68B9DA00841B04 /* ORKRangeOfMotionStepViewController.m */; };
959A2C0D1D68C91400841B04 /* ORKShoulderRangeOfMotionStep.h in Headers */ = {isa = PBXBuildFile; fileRef = 959A2C0B1D68C91400841B04 /* ORKShoulderRangeOfMotionStep.h */; settings = {ATTRIBUTES = (Private, ); }; };
959A2C0E1D68C91400841B04 /* ORKShoulderRangeOfMotionStep.m in Sources */ = {isa = PBXBuildFile; fileRef = 959A2C0C1D68C91400841B04 /* ORKShoulderRangeOfMotionStep.m */; };
95E11E551D73396300BF865B /* ORKShoulderRangeOfMotionStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 95E11E531D73396300BF865B /* ORKShoulderRangeOfMotionStepViewController.h */; };
95E11E561D73396300BF865B /* ORKShoulderRangeOfMotionStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 95E11E541D73396300BF865B /* ORKShoulderRangeOfMotionStepViewController.m */; };
B11C54991A9EEF8800265E61 /* ORKConsentSharingStep.h in Headers */ = {isa = PBXBuildFile; fileRef = B11C54961A9EEF8800265E61 /* ORKConsentSharingStep.h */; settings = {ATTRIBUTES = (Public, ); }; };
B11C549B1A9EEF8800265E61 /* ORKConsentSharingStep.m in Sources */ = {isa = PBXBuildFile; fileRef = B11C54971A9EEF8800265E61 /* ORKConsentSharingStep.m */; };
B11C549F1A9EF4A700265E61 /* ORKConsentSharingStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = B11C549C1A9EF4A700265E61 /* ORKConsentSharingStepViewController.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -462,6 +480,12 @@
B1C7955E1A9FBF04007279BA /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B1C7955D1A9FBF04007279BA /* HealthKit.framework */; settings = {ATTRIBUTES = (Required, ); }; };
B8760F2B1AFBEFB0007FA16F /* ORKScaleRangeDescriptionLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = B8760F291AFBEFB0007FA16F /* ORKScaleRangeDescriptionLabel.h */; };
B8760F2C1AFBEFB0007FA16F /* ORKScaleRangeDescriptionLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = B8760F2A1AFBEFB0007FA16F /* ORKScaleRangeDescriptionLabel.m */; };
BA0AA6941EAEC0B600671ACE /* ORKStroopContentView.h in Headers */ = {isa = PBXBuildFile; fileRef = BA0AA68E1EAEC0B600671ACE /* ORKStroopContentView.h */; };
BA0AA6951EAEC0B600671ACE /* ORKStroopContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = BA0AA68F1EAEC0B600671ACE /* ORKStroopContentView.m */; };
BA0AA6961EAEC0B600671ACE /* ORKStroopStep.h in Headers */ = {isa = PBXBuildFile; fileRef = BA0AA6901EAEC0B600671ACE /* ORKStroopStep.h */; settings = {ATTRIBUTES = (Private, ); }; };
BA0AA6971EAEC0B600671ACE /* ORKStroopStep.m in Sources */ = {isa = PBXBuildFile; fileRef = BA0AA6911EAEC0B600671ACE /* ORKStroopStep.m */; };
BA0AA6981EAEC0B600671ACE /* ORKStroopStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = BA0AA6921EAEC0B600671ACE /* ORKStroopStepViewController.h */; settings = {ATTRIBUTES = (Private, ); }; };
BA0AA6991EAEC0B600671ACE /* ORKStroopStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BA0AA6931EAEC0B600671ACE /* ORKStroopStepViewController.m */; };
BC01B0FB1B0EB99700863803 /* ORKTintedImageView_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = BC01B0FA1B0EB99700863803 /* ORKTintedImageView_Internal.h */; };
BC13CE391B0660220044153C /* ORKNavigableOrderedTask.h in Headers */ = {isa = PBXBuildFile; fileRef = BC13CE371B0660220044153C /* ORKNavigableOrderedTask.h */; settings = {ATTRIBUTES = (Public, ); }; };
BC13CE3A1B0660220044153C /* ORKNavigableOrderedTask.m in Sources */ = {isa = PBXBuildFile; fileRef = BC13CE381B0660220044153C /* ORKNavigableOrderedTask.m */; };
@@ -477,6 +501,9 @@
BC5FAF841C6901A200057CF1 /* ORKChartTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5FAF821C6901A200057CF1 /* ORKChartTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
BC5FAF851C6901A200057CF1 /* ORKChartTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = BC5FAF831C6901A200057CF1 /* ORKChartTypes.m */; };
BC8FC6781CA9B17C00D12768 /* ORKVoiceEngine_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EBFE11E1AE1B68800CB8254 /* ORKVoiceEngine_Internal.h */; };
BC94EF311E962F7400143081 /* ORKDeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = BC94EF2F1E962F7400143081 /* ORKDeprecated.h */; settings = {ATTRIBUTES = (Public, ); }; };
BC94EF321E962F7400143081 /* ORKDeprecated.m in Sources */ = {isa = PBXBuildFile; fileRef = BC94EF301E962F7400143081 /* ORKDeprecated.m */; };
BC94EF361E96394C00143081 /* ORKRegistrationStep_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = BC94EF351E96394C00143081 /* ORKRegistrationStep_Internal.h */; };
BCA5C0351AEC05F20092AC8D /* ORKStepNavigationRule.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA5C0331AEC05F20092AC8D /* ORKStepNavigationRule.h */; settings = {ATTRIBUTES = (Public, ); }; };
BCA5C0361AEC05F20092AC8D /* ORKStepNavigationRule.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA5C0341AEC05F20092AC8D /* ORKStepNavigationRule.m */; };
BCAD50E81B0201EE0034806A /* ORKTaskTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BCAD50E71B0201EE0034806A /* ORKTaskTests.m */; };
@@ -508,6 +535,10 @@
BCD192EC1B81245500FCC08A /* ORKPieChartTitleTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD192EA1B81245500FCC08A /* ORKPieChartTitleTextView.m */; };
BCD192EE1B81255F00FCC08A /* ORKPieChartView_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD192ED1B81255F00FCC08A /* ORKPieChartView_Internal.h */; };
BCFF24BD1B0798D10044EC35 /* ORKResultPredicate.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFF24BC1B0798D10044EC35 /* ORKResultPredicate.m */; };
BF1D43851D4904C6007EE90B /* ORKVideoInstructionStep.h in Headers */ = {isa = PBXBuildFile; fileRef = BF1D43831D4904C6007EE90B /* ORKVideoInstructionStep.h */; settings = {ATTRIBUTES = (Public, ); }; };
BF1D43861D4904C6007EE90B /* ORKVideoInstructionStep.m in Sources */ = {isa = PBXBuildFile; fileRef = BF1D43841D4904C6007EE90B /* ORKVideoInstructionStep.m */; };
BF1D43891D4905FC007EE90B /* ORKVideoInstructionStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = BF1D43871D4905FC007EE90B /* ORKVideoInstructionStepViewController.h */; settings = {ATTRIBUTES = (Private, ); }; };
BF1D438A1D4905FC007EE90B /* ORKVideoInstructionStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BF1D43881D4905FC007EE90B /* ORKVideoInstructionStepViewController.m */; };
BF5161501BE9C53D00174DDD /* ORKWaitStep.h in Headers */ = {isa = PBXBuildFile; fileRef = BF9155A11BDE8DA9007FA459 /* ORKWaitStep.h */; settings = {ATTRIBUTES = (Public, ); }; };
BF91559B1BDE8D7D007FA459 /* ORKReviewStep_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = BF9155951BDE8D7D007FA459 /* ORKReviewStep_Internal.h */; };
BF91559C1BDE8D7D007FA459 /* ORKReviewStep.h in Headers */ = {isa = PBXBuildFile; fileRef = BF9155961BDE8D7D007FA459 /* ORKReviewStep.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -544,11 +575,22 @@
FF36A49C1D1A15FC00DE8470 /* ORKTableStepViewController_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = FF36A4991D1A15FC00DE8470 /* ORKTableStepViewController_Internal.h */; };
FF36A49D1D1A15FC00DE8470 /* ORKTableStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = FF36A49A1D1A15FC00DE8470 /* ORKTableStepViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
FF36A49E1D1A15FC00DE8470 /* ORKTableStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FF36A49B1D1A15FC00DE8470 /* ORKTableStepViewController.m */; };
FF5051ED1D668FF80065E677 /* ORKPageStep_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = FF5051EC1D668FF80065E677 /* ORKPageStep_Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
FF5051F01D66908C0065E677 /* ORKNavigablePageStep.h in Headers */ = {isa = PBXBuildFile; fileRef = FF5051EE1D66908C0065E677 /* ORKNavigablePageStep.h */; settings = {ATTRIBUTES = (Public, ); }; };
FF5051F11D66908C0065E677 /* ORKNavigablePageStep.m in Sources */ = {isa = PBXBuildFile; fileRef = FF5051EF1D66908C0065E677 /* ORKNavigablePageStep.m */; };
FF5424531DF1513B00A86918 /* ORKHealthAnswerFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5424521DF1513B00A86918 /* ORKHealthAnswerFormat.swift */; };
FF5CA6121D2C2670001660A3 /* ORKTableStep.h in Headers */ = {isa = PBXBuildFile; fileRef = FF5CA6101D2C2670001660A3 /* ORKTableStep.h */; settings = {ATTRIBUTES = (Public, ); }; };
FF5CA6131D2C2670001660A3 /* ORKTableStep.m in Sources */ = {isa = PBXBuildFile; fileRef = FF5CA6111D2C2670001660A3 /* ORKTableStep.m */; };
FF5CA61B1D2C6453001660A3 /* ORKSignatureStep.h in Headers */ = {isa = PBXBuildFile; fileRef = FF5CA6191D2C6453001660A3 /* ORKSignatureStep.h */; settings = {ATTRIBUTES = (Public, ); }; };
FF5CA61C1D2C6453001660A3 /* ORKSignatureStep.m in Sources */ = {isa = PBXBuildFile; fileRef = FF5CA61A1D2C6453001660A3 /* ORKSignatureStep.m */; };
FFDF60D11D19E47D0004156F /* ORKTextButton_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = FB30E8571C7D030F0005AD25 /* ORKTextButton_Internal.h */; };
FF5E3CCB1D23444400ECE4B7 /* ORKPageStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = FF5E3CC91D23444400ECE4B7 /* ORKPageStepViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
FF5E3CCC1D23444400ECE4B7 /* ORKPageStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FF5E3CCA1D23444400ECE4B7 /* ORKPageStepViewController.m */; };
FFAE71401DAEC66200AE82B4 /* ORKFootnoteLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = FFAE713E1DAEC66200AE82B4 /* ORKFootnoteLabel.h */; };
FFAE71411DAEC66200AE82B4 /* ORKFootnoteLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = FFAE713F1DAEC66200AE82B4 /* ORKFootnoteLabel.m */; };
FFDDD8491D3555EA00446806 /* ORKPageStep.h in Headers */ = {isa = PBXBuildFile; fileRef = FFDDD8471D3555EA00446806 /* ORKPageStep.h */; settings = {ATTRIBUTES = (Public, ); }; };
FFDDD84A1D3555EA00446806 /* ORKPageStep.m in Sources */ = {isa = PBXBuildFile; fileRef = FFDDD8481D3555EA00446806 /* ORKPageStep.m */; };
FFF65AB81E318F2D0043FB40 /* ORKMultipleValuePicker.h in Headers */ = {isa = PBXBuildFile; fileRef = FFF65AB61E318F2D0043FB40 /* ORKMultipleValuePicker.h */; };
FFF65AB91E318F2D0043FB40 /* ORKMultipleValuePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = FFF65AB71E318F2D0043FB40 /* ORKMultipleValuePicker.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -674,6 +716,12 @@
618DA04A1A93D0D600E63AA8 /* ORKAccessibilityFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKAccessibilityFunctions.m; sourceTree = "<group>"; };
618DA04B1A93D0D600E63AA8 /* UIView+ORKAccessibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "UIView+ORKAccessibility.h"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
618DA04C1A93D0D600E63AA8 /* UIView+ORKAccessibility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = "UIView+ORKAccessibility.m"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
781D540A1DF886AB00223305 /* ORKTrailmakingContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKTrailmakingContentView.h; sourceTree = "<group>"; };
781D540B1DF886AB00223305 /* ORKTrailmakingContentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTrailmakingContentView.m; sourceTree = "<group>"; };
781D540C1DF886AB00223305 /* ORKTrailmakingStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKTrailmakingStep.h; sourceTree = "<group>"; };
781D540D1DF886AB00223305 /* ORKTrailmakingStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTrailmakingStep.m; sourceTree = "<group>"; };
781D540E1DF886AB00223305 /* ORKTrailmakingStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKTrailmakingStepViewController.h; sourceTree = "<group>"; };
781D540F1DF886AB00223305 /* ORKTrailmakingStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTrailmakingStepViewController.m; sourceTree = "<group>"; };
805685771C90C19500BF437A /* UIImage+ResearchKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+ResearchKit.h"; sourceTree = "<group>"; };
805685781C90C19500BF437A /* UIImage+ResearchKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+ResearchKit.m"; sourceTree = "<group>"; };
861610BF1A8D8EDD00245F7A /* Artwork.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Artwork.xcassets; sourceTree = "<group>"; };
@@ -984,6 +1032,18 @@
86CC8EAF1AC09383001CCD89 /* ORKResultTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKResultTests.m; sourceTree = "<group>"; };
86CC8EB01AC09383001CCD89 /* ORKTextChoiceCellGroupTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTextChoiceCellGroupTests.m; sourceTree = "<group>"; };
86D348001AC16175006DB02B /* ORKRecorderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ORKRecorderTests.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
9550E6711D58DBCF00C691B8 /* ORKTouchAnywhereStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKTouchAnywhereStep.h; sourceTree = "<group>"; };
9550E6721D58DBCF00C691B8 /* ORKTouchAnywhereStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTouchAnywhereStep.m; sourceTree = "<group>"; };
9550E67A1D58DD2000C691B8 /* ORKTouchAnywhereStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKTouchAnywhereStepViewController.h; sourceTree = "<group>"; };
9550E67B1D58DD2000C691B8 /* ORKTouchAnywhereStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTouchAnywhereStepViewController.m; sourceTree = "<group>"; };
959A2BFA1D68B98700841B04 /* ORKRangeOfMotionStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKRangeOfMotionStep.h; sourceTree = "<group>"; };
959A2BFB1D68B98700841B04 /* ORKRangeOfMotionStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKRangeOfMotionStep.m; sourceTree = "<group>"; };
959A2BFE1D68B9DA00841B04 /* ORKRangeOfMotionStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKRangeOfMotionStepViewController.h; sourceTree = "<group>"; };
959A2BFF1D68B9DA00841B04 /* ORKRangeOfMotionStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKRangeOfMotionStepViewController.m; sourceTree = "<group>"; };
959A2C0B1D68C91400841B04 /* ORKShoulderRangeOfMotionStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKShoulderRangeOfMotionStep.h; sourceTree = "<group>"; };
959A2C0C1D68C91400841B04 /* ORKShoulderRangeOfMotionStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKShoulderRangeOfMotionStep.m; sourceTree = "<group>"; };
95E11E531D73396300BF865B /* ORKShoulderRangeOfMotionStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKShoulderRangeOfMotionStepViewController.h; sourceTree = "<group>"; };
95E11E541D73396300BF865B /* ORKShoulderRangeOfMotionStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKShoulderRangeOfMotionStepViewController.m; sourceTree = "<group>"; };
B11C54961A9EEF8800265E61 /* ORKConsentSharingStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKConsentSharingStep.h; sourceTree = "<group>"; };
B11C54971A9EEF8800265E61 /* ORKConsentSharingStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKConsentSharingStep.m; sourceTree = "<group>"; };
B11C549C1A9EF4A700265E61 /* ORKConsentSharingStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKConsentSharingStepViewController.h; sourceTree = "<group>"; };
@@ -996,7 +1056,7 @@
B12EA0181B0D76AD00F9F554 /* ORKToneAudiometryPracticeStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKToneAudiometryPracticeStepViewController.m; sourceTree = "<group>"; };
B14660481AA10DD7002F95C2 /* zh_TW */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; name = zh_TW; path = zh_TW.lproj/ResearchKit.strings; sourceTree = "<group>"; };
B183A5951A8535D100C76870 /* ResearchKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ResearchKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B18AABE01A9F08D9003871B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = "<group>"; };
B18AABE01A9F08D9003871B5 /* ResearchKit.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = ResearchKit.modulemap; sourceTree = "<group>"; };
B1A860DB1A9693C400EA57B7 /* consent_01@2x.m4v */ = {isa = PBXFileReference; lastKnownFileType = file; path = "consent_01@2x.m4v"; sourceTree = "<group>"; };
B1A860DC1A9693C400EA57B7 /* consent_02@2x.m4v */ = {isa = PBXFileReference; lastKnownFileType = file; path = "consent_02@2x.m4v"; sourceTree = "<group>"; };
B1A860DD1A9693C400EA57B7 /* consent_03@2x.m4v */ = {isa = PBXFileReference; lastKnownFileType = file; path = "consent_03@2x.m4v"; sourceTree = "<group>"; };
@@ -1037,7 +1097,7 @@
B1B349FB1AA10EA8005FAD66 /* fr_CA */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; name = fr_CA; path = fr_CA.lproj/ResearchKit.strings; sourceTree = "<group>"; };
B1B349FC1AA10EAE005FAD66 /* fi */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; name = fi; path = fi.lproj/ResearchKit.strings; sourceTree = "<group>"; };
B1B349FD1AA10EB4005FAD66 /* es */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; name = es; path = es.lproj/ResearchKit.strings; sourceTree = "<group>"; };
B1B349FE1AA10EBA005FAD66 /* es_MX */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; name = es_MX; path = es_MX.lproj/ResearchKit.strings; sourceTree = "<group>"; };
B1B349FE1AA10EBA005FAD66 /* es_MX */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; name = es_MX; path = es_419.lproj/ResearchKit.strings; sourceTree = "<group>"; };
B1B349FF1AA10EC1005FAD66 /* en_GB */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; name = en_GB; path = en_GB.lproj/ResearchKit.strings; sourceTree = "<group>"; };
B1B34A001AA10EC6005FAD66 /* en_AU */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; name = en_AU; path = en_AU.lproj/ResearchKit.strings; sourceTree = "<group>"; };
B1B34A011AA10ECB005FAD66 /* el */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; name = el; path = el.lproj/ResearchKit.strings; sourceTree = "<group>"; };
@@ -1046,13 +1106,19 @@
B1B34A041AA10EDA005FAD66 /* cs */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; name = cs; path = cs.lproj/ResearchKit.strings; sourceTree = "<group>"; };
B1B34A051AA10EDF005FAD66 /* ca */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; name = ca; path = ca.lproj/ResearchKit.strings; sourceTree = "<group>"; };
B1B34A061AA10EE4005FAD66 /* ar */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; name = ar; path = ar.lproj/ResearchKit.strings; sourceTree = "<group>"; };
B1B34A061AABBCCDDEEFFAAA /* no */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; name = no; path = no.lproj/ResearchKit.strings; sourceTree = "<group>"; };
B1B34A061AABBCCDDEEFFAAA /* no */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; name = no; path = nb.lproj/ResearchKit.strings; sourceTree = "<group>"; };
B1B894391A00345200C5CF2D /* ResearchKit_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ResearchKit_Private.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
B1C0F4E21A9BA65F0022C153 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/ResearchKit.strings; sourceTree = "<group>"; };
B1C1DE4F196F541F00F75544 /* ResearchKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResearchKit.h; sourceTree = "<group>"; };
B1C7955D1A9FBF04007279BA /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; };
B8760F291AFBEFB0007FA16F /* ORKScaleRangeDescriptionLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKScaleRangeDescriptionLabel.h; sourceTree = "<group>"; };
B8760F2A1AFBEFB0007FA16F /* ORKScaleRangeDescriptionLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKScaleRangeDescriptionLabel.m; sourceTree = "<group>"; };
BA0AA68E1EAEC0B600671ACE /* ORKStroopContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKStroopContentView.h; sourceTree = "<group>"; };
BA0AA68F1EAEC0B600671ACE /* ORKStroopContentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKStroopContentView.m; sourceTree = "<group>"; };
BA0AA6901EAEC0B600671ACE /* ORKStroopStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKStroopStep.h; sourceTree = "<group>"; };
BA0AA6911EAEC0B600671ACE /* ORKStroopStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKStroopStep.m; sourceTree = "<group>"; };
BA0AA6921EAEC0B600671ACE /* ORKStroopStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKStroopStepViewController.h; sourceTree = "<group>"; };
BA0AA6931EAEC0B600671ACE /* ORKStroopStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKStroopStepViewController.m; sourceTree = "<group>"; };
BC01B0FA1B0EB99700863803 /* ORKTintedImageView_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKTintedImageView_Internal.h; sourceTree = "<group>"; };
BC13CE371B0660220044153C /* ORKNavigableOrderedTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKNavigableOrderedTask.h; sourceTree = "<group>"; };
BC13CE381B0660220044153C /* ORKNavigableOrderedTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKNavigableOrderedTask.m; sourceTree = "<group>"; };
@@ -1067,6 +1133,9 @@
BC4A213E1C85FC0000BFC271 /* ORKBarGraphChartView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKBarGraphChartView.m; path = Charts/ORKBarGraphChartView.m; sourceTree = "<group>"; };
BC5FAF821C6901A200057CF1 /* ORKChartTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKChartTypes.h; path = Charts/ORKChartTypes.h; sourceTree = "<group>"; };
BC5FAF831C6901A200057CF1 /* ORKChartTypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKChartTypes.m; path = Charts/ORKChartTypes.m; sourceTree = "<group>"; };
BC94EF2F1E962F7400143081 /* ORKDeprecated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKDeprecated.h; sourceTree = "<group>"; };
BC94EF301E962F7400143081 /* ORKDeprecated.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKDeprecated.m; sourceTree = "<group>"; };
BC94EF351E96394C00143081 /* ORKRegistrationStep_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKRegistrationStep_Internal.h; path = Onboarding/ORKRegistrationStep_Internal.h; sourceTree = "<group>"; };
BCA5C0331AEC05F20092AC8D /* ORKStepNavigationRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKStepNavigationRule.h; sourceTree = "<group>"; };
BCA5C0341AEC05F20092AC8D /* ORKStepNavigationRule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKStepNavigationRule.m; sourceTree = "<group>"; };
BCAD50E71B0201EE0034806A /* ORKTaskTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTaskTests.m; sourceTree = "<group>"; };
@@ -1099,6 +1168,10 @@
BCD192ED1B81255F00FCC08A /* ORKPieChartView_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKPieChartView_Internal.h; path = Charts/ORKPieChartView_Internal.h; sourceTree = "<group>"; };
BCFB2EAF1AE70E4E0070B5D0 /* ORKConsentSceneViewController_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ORKConsentSceneViewController_Internal.h; sourceTree = "<group>"; };
BCFF24BC1B0798D10044EC35 /* ORKResultPredicate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKResultPredicate.m; sourceTree = "<group>"; };
BF1D43831D4904C6007EE90B /* ORKVideoInstructionStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKVideoInstructionStep.h; sourceTree = "<group>"; };
BF1D43841D4904C6007EE90B /* ORKVideoInstructionStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKVideoInstructionStep.m; sourceTree = "<group>"; };
BF1D43871D4905FC007EE90B /* ORKVideoInstructionStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKVideoInstructionStepViewController.h; sourceTree = "<group>"; };
BF1D43881D4905FC007EE90B /* ORKVideoInstructionStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKVideoInstructionStepViewController.m; sourceTree = "<group>"; };
BF9155951BDE8D7D007FA459 /* ORKReviewStep_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKReviewStep_Internal.h; sourceTree = "<group>"; };
BF9155961BDE8D7D007FA459 /* ORKReviewStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKReviewStep.h; sourceTree = "<group>"; };
BF9155971BDE8D7D007FA459 /* ORKReviewStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKReviewStep.m; sourceTree = "<group>"; };
@@ -1130,16 +1203,27 @@
FA7A9D321B0843A9005A2BEA /* ORKConsentSignatureFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKConsentSignatureFormatter.m; sourceTree = "<group>"; };
FA7A9D361B09365F005A2BEA /* ORKConsentSectionFormatterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKConsentSectionFormatterTests.m; sourceTree = "<group>"; };
FA7A9D381B0969A7005A2BEA /* ORKConsentSignatureFormatterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKConsentSignatureFormatterTests.m; sourceTree = "<group>"; };
FB30E8571C7D030F0005AD25 /* ORKTextButton_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ORKTextButton_Internal.h; path = ../../../ResearchKit/ResearchKit/Common/ORKTextButton_Internal.h; sourceTree = "<group>"; };
FF36A48B1D1A0ACA00DE8470 /* ORKAudioLevelNavigationRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKAudioLevelNavigationRule.h; sourceTree = "<group>"; };
FF36A48C1D1A0ACA00DE8470 /* ORKAudioLevelNavigationRule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKAudioLevelNavigationRule.m; sourceTree = "<group>"; };
FF36A4991D1A15FC00DE8470 /* ORKTableStepViewController_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKTableStepViewController_Internal.h; sourceTree = "<group>"; };
FF36A49A1D1A15FC00DE8470 /* ORKTableStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKTableStepViewController.h; sourceTree = "<group>"; };
FF36A49B1D1A15FC00DE8470 /* ORKTableStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTableStepViewController.m; sourceTree = "<group>"; };
FF5051EC1D668FF80065E677 /* ORKPageStep_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKPageStep_Private.h; sourceTree = "<group>"; };
FF5051EE1D66908C0065E677 /* ORKNavigablePageStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKNavigablePageStep.h; sourceTree = "<group>"; };
FF5051EF1D66908C0065E677 /* ORKNavigablePageStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKNavigablePageStep.m; sourceTree = "<group>"; };
FF5424521DF1513B00A86918 /* ORKHealthAnswerFormat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ORKHealthAnswerFormat.swift; sourceTree = "<group>"; };
FF5CA6101D2C2670001660A3 /* ORKTableStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKTableStep.h; sourceTree = "<group>"; };
FF5CA6111D2C2670001660A3 /* ORKTableStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTableStep.m; sourceTree = "<group>"; };
FF5CA6191D2C6453001660A3 /* ORKSignatureStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKSignatureStep.h; sourceTree = "<group>"; };
FF5CA61A1D2C6453001660A3 /* ORKSignatureStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKSignatureStep.m; sourceTree = "<group>"; };
FF5E3CC91D23444400ECE4B7 /* ORKPageStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKPageStepViewController.h; sourceTree = "<group>"; };
FF5E3CCA1D23444400ECE4B7 /* ORKPageStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKPageStepViewController.m; sourceTree = "<group>"; };
FFAE713E1DAEC66200AE82B4 /* ORKFootnoteLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKFootnoteLabel.h; sourceTree = "<group>"; };
FFAE713F1DAEC66200AE82B4 /* ORKFootnoteLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKFootnoteLabel.m; sourceTree = "<group>"; };
FFDDD8471D3555EA00446806 /* ORKPageStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKPageStep.h; sourceTree = "<group>"; };
FFDDD8481D3555EA00446806 /* ORKPageStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKPageStep.m; sourceTree = "<group>"; };
FFF65AB61E318F2D0043FB40 /* ORKMultipleValuePicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKMultipleValuePicker.h; sourceTree = "<group>"; };
FFF65AB71E318F2D0043FB40 /* ORKMultipleValuePicker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKMultipleValuePicker.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -1271,6 +1355,7 @@
isa = PBXGroup;
children = (
2429D5701BBB5397003A512F /* ORKRegistrationStep.h */,
BC94EF351E96394C00143081 /* ORKRegistrationStep_Internal.h */,
2429D5711BBB5397003A512F /* ORKRegistrationStep.m */,
242C9E031BBDFDAC0088B7F4 /* ORKVerificationStep.h */,
242C9E041BBDFDAC0088B7F4 /* ORKVerificationStep.m */,
@@ -1470,6 +1555,19 @@
path = Accessibility;
sourceTree = "<group>";
};
781D54091DF884C400223305 /* Trailmaking */ = {
isa = PBXGroup;
children = (
781D540A1DF886AB00223305 /* ORKTrailmakingContentView.h */,
781D540B1DF886AB00223305 /* ORKTrailmakingContentView.m */,
781D540C1DF886AB00223305 /* ORKTrailmakingStep.h */,
781D540D1DF886AB00223305 /* ORKTrailmakingStep.m */,
781D540E1DF886AB00223305 /* ORKTrailmakingStepViewController.h */,
781D540F1DF886AB00223305 /* ORKTrailmakingStepViewController.m */,
);
name = Trailmaking;
sourceTree = "<group>";
};
866DA5121D63D01C00C9AF3F /* DataCollection */ = {
isa = PBXGroup;
children = (
@@ -1494,6 +1592,8 @@
children = (
B1C1DE4F196F541F00F75544 /* ResearchKit.h */,
B1B894391A00345200C5CF2D /* ResearchKit_Private.h */,
BC94EF2F1E962F7400143081 /* ORKDeprecated.h */,
BC94EF301E962F7400143081 /* ORKDeprecated.m */,
86C40B511A8D7C5B00081FAC /* Common */,
86C40AF91A8D7C5B00081FAC /* Active Tasks */,
259E76FB1AFFAEAC0070F786 /* Charts */,
@@ -1504,7 +1604,7 @@
861610BF1A8D8EDD00245F7A /* Artwork.xcassets */,
B1C0F4E01A9BA65F0022C153 /* Localized */,
86C40C101A8D7C5C00081FAC /* Info.plist */,
B18AABE01A9F08D9003871B5 /* module.modulemap */,
B18AABE01A9F08D9003871B5 /* ResearchKit.modulemap */,
);
path = ResearchKit;
sourceTree = "<group>";
@@ -1517,12 +1617,15 @@
B12EFF5D1AB2177700A80147 /* Fitness */,
B12EFF5E1AB2177D00A80147 /* Spatial Span Memory */,
25F5CEDC1B4C3F1D0031E2A4 /* TowerOfHanoi */,
BA0AA68D1EAEC06A00671ACE /* Stroop */,
B12EFF5F1AB2178500A80147 /* Tapping */,
10BAA2CC1B5FCDB1004FE478 /* Walking */,
147503AC1AEE8058004B17F3 /* Tone Audiometry */,
106FF29B1B663F5C004EACF2 /* Hole Peg Test */,
25ECC0921AFBD64800F3D63B /* Reaction Time */,
10864C951B271456000F4158 /* PSAT */,
95E25CF71D39FB240089C0B8 /* Range of Motion */,
781D54091DF884C400223305 /* Trailmaking */,
);
name = "Active Tasks";
path = ActiveTasks;
@@ -1581,6 +1684,40 @@
path = ResearchKitTests;
sourceTree = "<group>";
};
9550E6701D58DB9A00C691B8 /* Touch Anywhere Step */ = {
isa = PBXGroup;
children = (
9550E6711D58DBCF00C691B8 /* ORKTouchAnywhereStep.h */,
9550E6721D58DBCF00C691B8 /* ORKTouchAnywhereStep.m */,
9550E67A1D58DD2000C691B8 /* ORKTouchAnywhereStepViewController.h */,
9550E67B1D58DD2000C691B8 /* ORKTouchAnywhereStepViewController.m */,
);
name = "Touch Anywhere Step";
sourceTree = "<group>";
};
959A2C0A1D68C8F100841B04 /* Shoulder */ = {
isa = PBXGroup;
children = (
959A2C0B1D68C91400841B04 /* ORKShoulderRangeOfMotionStep.h */,
959A2C0C1D68C91400841B04 /* ORKShoulderRangeOfMotionStep.m */,
95E11E531D73396300BF865B /* ORKShoulderRangeOfMotionStepViewController.h */,
95E11E541D73396300BF865B /* ORKShoulderRangeOfMotionStepViewController.m */,
);
name = Shoulder;
sourceTree = "<group>";
};
95E25CF71D39FB240089C0B8 /* Range of Motion */ = {
isa = PBXGroup;
children = (
959A2C0A1D68C8F100841B04 /* Shoulder */,
959A2BFA1D68B98700841B04 /* ORKRangeOfMotionStep.h */,
959A2BFB1D68B98700841B04 /* ORKRangeOfMotionStep.m */,
959A2BFE1D68B9DA00841B04 /* ORKRangeOfMotionStepViewController.h */,
959A2BFF1D68B9DA00841B04 /* ORKRangeOfMotionStepViewController.m */,
);
name = "Range of Motion";
sourceTree = "<group>";
};
B11DF3B21AA109C8009E76D2 /* docs */ = {
isa = PBXGroup;
children = (
@@ -1618,6 +1755,8 @@
86C40B7A1A8D7C5C00081FAC /* ORKDefaultFont.h */,
106FF2AC1B6FACA8004EACF2 /* ORKDirectionView.h */,
106FF2AD1B6FACA8004EACF2 /* ORKDirectionView.m */,
FFAE713E1DAEC66200AE82B4 /* ORKFootnoteLabel.h */,
FFAE713F1DAEC66200AE82B4 /* ORKFootnoteLabel.m */,
86C40B881A8D7C5C00081FAC /* ORKHeadlineLabel.h */,
86C40B891A8D7C5C00081FAC /* ORKHeadlineLabel.m */,
86C40B901A8D7C5C00081FAC /* ORKImageChoiceLabel.h */,
@@ -1716,6 +1855,7 @@
D44239761AF17EE700559D96 /* Image Capture Step */,
2489F7A61D65213D008DEF20 /* Video Capture Step */,
24A4DA091B8D0CC8009C797A /* Passcode Step */,
FFDDD8461D3453A200446806 /* Page Step */,
FF5CA60F1D2C2630001660A3 /* Table Step */,
BF9D62C41BD244C4000AA6A7 /* Wait Step */,
BF690AD61BAD3DC0009C5ADA /* Review Step */,
@@ -1735,6 +1875,7 @@
86C40B5A1A8D7C5B00081FAC /* ORKInstructionStepView.h */,
86C40B5B1A8D7C5B00081FAC /* ORKInstructionStepView.m */,
B12EFF301AB20E7500A80147 /* Completion Step */,
BF1D43821D490482007EE90B /* Video Instruction Step */,
);
name = "Instruction Step";
sourceTree = "<group>";
@@ -1785,16 +1926,17 @@
B12EFF3B1AB211E000A80147 /* Answer Format */ = {
isa = PBXGroup;
children = (
B12EFF421AB2134100A80147 /* Choice Format Helpers */,
B12EFF411AB212E100A80147 /* Control Views */,
B12EFF3E1AB2123000A80147 /* Form Step Views */,
B12EFF3F1AB2125E00A80147 /* Question Step Views */,
86C40B641A8D7C5B00081FAC /* ORKAnswerFormat.h */,
86C40B651A8D7C5B00081FAC /* ORKAnswerFormat.m */,
86C40B661A8D7C5B00081FAC /* ORKAnswerFormat_Internal.h */,
244EFAD11BCEFD83001850D9 /* ORKAnswerFormat_Private.h */,
86C40B8A1A8D7C5C00081FAC /* ORKHealthAnswerFormat.h */,
86C40B8B1A8D7C5C00081FAC /* ORKHealthAnswerFormat.m */,
B12EFF421AB2134100A80147 /* Choice Format Helpers */,
B12EFF411AB212E100A80147 /* Control Views */,
B12EFF3E1AB2123000A80147 /* Form Step Views */,
B12EFF3F1AB2125E00A80147 /* Question Step Views */,
FF5424521DF1513B00A86918 /* ORKHealthAnswerFormat.swift */,
);
name = "Answer Format";
sourceTree = "<group>";
@@ -1884,6 +2026,8 @@
865EA1611AB8DF750037C68E /* ORKDateTimePicker.m */,
865EA1661ABA1AA10037C68E /* ORKPicker.h */,
865EA1671ABA1AA10037C68E /* ORKPicker.m */,
FFF65AB61E318F2D0043FB40 /* ORKMultipleValuePicker.h */,
FFF65AB71E318F2D0043FB40 /* ORKMultipleValuePicker.m */,
);
name = "Control Views";
sourceTree = "<group>";
@@ -2033,6 +2177,7 @@
B12EFF4F1AB2165B00A80147 /* Common */ = {
isa = PBXGroup;
children = (
9550E6701D58DB9A00C691B8 /* Touch Anywhere Step */,
B12EFF501AB2167400A80147 /* Active Step */,
B12EFF5C1AB2175B00A80147 /* Countdown Step */,
B12EFF531AB216AA00A80147 /* Recorders */,
@@ -2221,12 +2366,12 @@
B12EFF5F1AB2178500A80147 /* Tapping */ = {
isa = PBXGroup;
children = (
86C40B181A8D7C5B00081FAC /* ORKTappingContentView.h */,
86C40B191A8D7C5B00081FAC /* ORKTappingContentView.m */,
86C40B1A1A8D7C5B00081FAC /* ORKTappingIntervalStep.h */,
86C40B1B1A8D7C5B00081FAC /* ORKTappingIntervalStep.m */,
86C40B1C1A8D7C5B00081FAC /* ORKTappingIntervalStepViewController.h */,
86C40B1D1A8D7C5B00081FAC /* ORKTappingIntervalStepViewController.m */,
86C40B181A8D7C5B00081FAC /* ORKTappingContentView.h */,
86C40B191A8D7C5B00081FAC /* ORKTappingContentView.m */,
);
name = Tapping;
sourceTree = "<group>";
@@ -2297,6 +2442,19 @@
path = Localized;
sourceTree = "<group>";
};
BA0AA68D1EAEC06A00671ACE /* Stroop */ = {
isa = PBXGroup;
children = (
BA0AA68E1EAEC0B600671ACE /* ORKStroopContentView.h */,
BA0AA68F1EAEC0B600671ACE /* ORKStroopContentView.m */,
BA0AA6901EAEC0B600671ACE /* ORKStroopStep.h */,
BA0AA6911EAEC0B600671ACE /* ORKStroopStep.m */,
BA0AA6921EAEC0B600671ACE /* ORKStroopStepViewController.h */,
BA0AA6931EAEC0B600671ACE /* ORKStroopStepViewController.m */,
);
name = Stroop;
sourceTree = "<group>";
};
BC4194261AE8451F00073D6B /* Misc */ = {
isa = PBXGroup;
children = (
@@ -2306,6 +2464,17 @@
name = Misc;
sourceTree = "<group>";
};
BF1D43821D490482007EE90B /* Video Instruction Step */ = {
isa = PBXGroup;
children = (
BF1D43831D4904C6007EE90B /* ORKVideoInstructionStep.h */,
BF1D43841D4904C6007EE90B /* ORKVideoInstructionStep.m */,
BF1D43871D4905FC007EE90B /* ORKVideoInstructionStepViewController.h */,
BF1D43881D4905FC007EE90B /* ORKVideoInstructionStepViewController.m */,
);
name = "Video Instruction Step";
sourceTree = "<group>";
};
BF690AD61BAD3DC0009C5ADA /* Review Step */ = {
isa = PBXGroup;
children = (
@@ -2381,6 +2550,20 @@
name = "Table Step";
sourceTree = "<group>";
};
FFDDD8461D3453A200446806 /* Page Step */ = {
isa = PBXGroup;
children = (
FFDDD8471D3555EA00446806 /* ORKPageStep.h */,
FFDDD8481D3555EA00446806 /* ORKPageStep.m */,
FF5051EC1D668FF80065E677 /* ORKPageStep_Private.h */,
FF5051EE1D66908C0065E677 /* ORKNavigablePageStep.h */,
FF5051EF1D66908C0065E677 /* ORKNavigablePageStep.m */,
FF5E3CC91D23444400ECE4B7 /* ORKPageStepViewController.h */,
FF5E3CCA1D23444400ECE4B7 /* ORKPageStepViewController.m */,
);
name = "Page Step";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@@ -2388,6 +2571,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
BF1D43851D4904C6007EE90B /* ORKVideoInstructionStep.h in Headers */,
BF5161501BE9C53D00174DDD /* ORKWaitStep.h in Headers */,
244EFAD21BCEFD83001850D9 /* ORKAnswerFormat_Private.h in Headers */,
BCA5C0351AEC05F20092AC8D /* ORKStepNavigationRule.h in Headers */,
@@ -2397,6 +2581,7 @@
BCB6E65B1B7D534C000D5B34 /* ORKDiscreteGraphChartView.h in Headers */,
86C40D8E1A8D7C5C00081FAC /* ORKStep.h in Headers */,
618DA04E1A93D0D600E63AA8 /* ORKAccessibility.h in Headers */,
FFF65AB81E318F2D0043FB40 /* ORKMultipleValuePicker.h in Headers */,
86B781BB1AA668ED00688151 /* ORKTimeIntervalPicker.h in Headers */,
24C296751BD052F800B42EF1 /* ORKVerificationStep_Internal.h in Headers */,
86C40C6A1A8D7C5C00081FAC /* CMDeviceMotion+ORKJSONDictionary.h in Headers */,
@@ -2415,8 +2600,10 @@
86C40C961A8D7C5C00081FAC /* ORKDataLogger.h in Headers */,
BC13CE421B066A990044153C /* ORKStepNavigationRule_Internal.h in Headers */,
86C40D781A8D7C5C00081FAC /* ORKScaleSlider.h in Headers */,
BA0AA6981EAEC0B600671ACE /* ORKStroopStepViewController.h in Headers */,
861D2AE81B840991008C4CD0 /* ORKTimedWalkStep.h in Headers */,
86C40D241A8D7C5C00081FAC /* ORKFormStepViewController.h in Headers */,
959A2C001D68B9DA00841B04 /* ORKRangeOfMotionStepViewController.h in Headers */,
86C40D6A1A8D7C5C00081FAC /* ORKResult.h in Headers */,
86C40DD61A8D7C5C00081FAC /* ORKUnitLabel.h in Headers */,
10FF9AD71B7A045E00ECB5B4 /* ORKSeparatorView.h in Headers */,
@@ -2437,11 +2624,13 @@
BF91559F1BDE8D7E007FA459 /* ORKReviewStepViewController.h in Headers */,
BF91559B1BDE8D7D007FA459 /* ORKReviewStep_Internal.h in Headers */,
BF91559E1BDE8D7E007FA459 /* ORKReviewStepViewController_Internal.h in Headers */,
FFAE71401DAEC66200AE82B4 /* ORKFootnoteLabel.h in Headers */,
FF5CA61B1D2C6453001660A3 /* ORKSignatureStep.h in Headers */,
25ECC0A31AFBDD2700F3D63B /* ORKReactionTimeStimulusView.h in Headers */,
106FF2AA1B690FD7004EACF2 /* ORKHolePegTestPlacePegView.h in Headers */,
86C40D701A8D7C5C00081FAC /* ORKRoundTappingButton.h in Headers */,
BCB6E6501B7D533B000D5B34 /* ORKPieChartLegendCollectionViewLayout.h in Headers */,
BF1D43891D4905FC007EE90B /* ORKVideoInstructionStepViewController.h in Headers */,
CBD34A561BB1FB9000F204EA /* ORKLocationSelectionView.h in Headers */,
865EA1621AB8DF750037C68E /* ORKDateTimePicker.h in Headers */,
86C40DA01A8D7C5C00081FAC /* ORKSurveyAnswerCell.h in Headers */,
@@ -2457,13 +2646,16 @@
86C40C3A1A8D7C5C00081FAC /* ORKSpatialSpanGameState.h in Headers */,
10864CA21B27146B000F4158 /* ORKPSATContentView.h in Headers */,
618DA0501A93D0D600E63AA8 /* ORKAccessibilityFunctions.h in Headers */,
FF5E3CCB1D23444400ECE4B7 /* ORKPageStepViewController.h in Headers */,
86C40C721A8D7C5C00081FAC /* CMPedometerData+ORKJSONDictionary.h in Headers */,
106FF2A61B665CF5004EACF2 /* ORKHolePegTestPlaceContentView.h in Headers */,
86C40CA41A8D7C5C00081FAC /* ORKLocationRecorder.h in Headers */,
86C40D201A8D7C5C00081FAC /* ORKFormStep.h in Headers */,
BCD192EB1B81245500FCC08A /* ORKPieChartTitleTextView.h in Headers */,
249F44E51BCD9EAC0000D57E /* ORKFormStepViewController_Internal.h in Headers */,
781D54101DF886AB00223305 /* ORKTrailmakingContentView.h in Headers */,
86C40C761A8D7C5C00081FAC /* HKSample+ORKJSONDictionary.h in Headers */,
BA0AA6961EAEC0B600671ACE /* ORKStroopStep.h in Headers */,
86C40CEA1A8D7C5C00081FAC /* ORKAnswerTextField.h in Headers */,
B12EA0191B0D76AD00F9F554 /* ORKToneAudiometryPracticeStepViewController.h in Headers */,
2429D5721BBB5397003A512F /* ORKRegistrationStep.h in Headers */,
@@ -2471,6 +2663,7 @@
242C9E111BBE06DE0088B7F4 /* ORKVerificationStepView.h in Headers */,
86C40CE81A8D7C5C00081FAC /* ORKAnswerFormat_Internal.h in Headers */,
106FF29E1B663FCE004EACF2 /* ORKHolePegTestPlaceStep.h in Headers */,
BC94EF361E96394C00143081 /* ORKRegistrationStep_Internal.h in Headers */,
86C40D021A8D7C5C00081FAC /* ORKContinueButton.h in Headers */,
86C40D681A8D7C5C00081FAC /* ORKQuestionStepViewController_Private.h in Headers */,
BCB6E6661B7D535F000D5B34 /* ORKXAxisView.h in Headers */,
@@ -2478,6 +2671,7 @@
86C40D401A8D7C5C00081FAC /* ORKInstructionStep.h in Headers */,
147503B71AEE807C004B17F3 /* ORKToneAudiometryContentView.h in Headers */,
86C40D981A8D7C5C00081FAC /* ORKStepViewController_Internal.h in Headers */,
959A2C0D1D68C91400841B04 /* ORKShoulderRangeOfMotionStep.h in Headers */,
86B89ABB1AB3BECC001626A4 /* ORKStepHeaderView.h in Headers */,
FF36A49D1D1A15FC00DE8470 /* ORKTableStepViewController.h in Headers */,
2489F7B51D65214D008DEF20 /* ORKVideoCaptureView.h in Headers */,
@@ -2508,6 +2702,7 @@
BCB6E6601B7D534C000D5B34 /* ORKLineGraphChartView.h in Headers */,
86C40E241A8D7C5C00081FAC /* ORKEAGLMoviePlayerView.h in Headers */,
B183A4DD1A8535D100C76870 /* ResearchKit.h in Headers */,
95E11E551D73396300BF865B /* ORKShoulderRangeOfMotionStepViewController.h in Headers */,
86C40D101A8D7C5C00081FAC /* ORKDefaultFont.h in Headers */,
86C40E301A8D7C5C00081FAC /* ORKVisualConsentStepViewController.h in Headers */,
86C40DCA1A8D7C5C00081FAC /* ORKTaskViewController.h in Headers */,
@@ -2548,7 +2743,6 @@
86C40DA61A8D7C5C00081FAC /* ORKSurveyAnswerCellForImageSelection.h in Headers */,
86C40D5E1A8D7C5C00081FAC /* ORKQuestionStep.h in Headers */,
6146D0A31B84A91E0068491D /* ORKLineGraphAccessibilityElement.h in Headers */,
FFDF60D11D19E47D0004156F /* ORKTextButton_Internal.h in Headers */,
86C40C841A8D7C5C00081FAC /* ORKActiveStepTimer.h in Headers */,
86B781BD1AA668ED00688151 /* ORKValuePicker.h in Headers */,
86C40DE21A8D7C5C00081FAC /* ORKVerticalContainerView_Internal.h in Headers */,
@@ -2556,6 +2750,7 @@
86B89ABE1AB3BFDB001626A4 /* ORKStepHeaderView_Internal.h in Headers */,
BC8FC6781CA9B17C00D12768 /* ORKVoiceEngine_Internal.h in Headers */,
86C40C1E1A8D7C5C00081FAC /* ORKAudioStepViewController.h in Headers */,
FFDDD8491D3555EA00446806 /* ORKPageStep.h in Headers */,
147503AF1AEE8071004B17F3 /* ORKAudioGenerator.h in Headers */,
86AD91141AB7B97E00361FEB /* ORKQuestionStepView.h in Headers */,
86C40C621A8D7C5C00081FAC /* CLLocation+ORKJSONDictionary.h in Headers */,
@@ -2568,6 +2763,7 @@
86C40C161A8D7C5C00081FAC /* ORKAudioContentView.h in Headers */,
86C40CB41A8D7C5C00081FAC /* ORKTouchRecorder.h in Headers */,
86C40DEA1A8D7C5C00081FAC /* UIBarButtonItem+ORKBarButtonItem.h in Headers */,
9550E6731D58DBCF00C691B8 /* ORKTouchAnywhereStep.h in Headers */,
86C40CF61A8D7C5C00081FAC /* ORKBorderedButton.h in Headers */,
86C40D4A1A8D7C5C00081FAC /* ORKLabel.h in Headers */,
250F94041B4C5A6600FA23EB /* ORKTowerOfHanoiStep.h in Headers */,
@@ -2588,6 +2784,7 @@
86C40C2A1A8D7C5C00081FAC /* ORKFitnessContentView.h in Headers */,
86C40DC21A8D7C5C00081FAC /* ORKTapCountLabel.h in Headers */,
86C40D301A8D7C5C00081FAC /* ORKHealthAnswerFormat.h in Headers */,
781D54141DF886AB00223305 /* ORKTrailmakingStepViewController.h in Headers */,
86C40C261A8D7C5C00081FAC /* ORKCountdownStepViewController.h in Headers */,
861D2AF01B8409D9008C4CD0 /* ORKTimedWalkContentView.h in Headers */,
2489F7B31D65214D008DEF20 /* ORKVideoCaptureStepViewController.h in Headers */,
@@ -2601,11 +2798,14 @@
86C40C821A8D7C5C00081FAC /* ORKActiveStep_Internal.h in Headers */,
86C40D481A8D7C5C00081FAC /* ORKInstructionStepViewController_Internal.h in Headers */,
86C40D341A8D7C5C00081FAC /* ORKHelpers_Internal.h in Headers */,
BA0AA6941EAEC0B600671ACE /* ORKStroopContentView.h in Headers */,
FA7A9D2F1B083DD3005A2BEA /* ORKConsentSectionFormatter.h in Headers */,
86C40E341A8D7C5C00081FAC /* ORKVisualConsentStepViewController_Internal.h in Headers */,
86C40D381A8D7C5C00081FAC /* ORKHTMLPDFWriter.h in Headers */,
959A2BFC1D68B98700841B04 /* ORKRangeOfMotionStep.h in Headers */,
86C40D561A8D7C5C00081FAC /* ORKOrderedTask.h in Headers */,
86C40C4E1A8D7C5C00081FAC /* ORKTappingContentView.h in Headers */,
FF5051F01D66908C0065E677 /* ORKNavigablePageStep.h in Headers */,
86C40CA01A8D7C5C00081FAC /* ORKHealthQuantityTypeRecorder.h in Headers */,
24850E191BCDA9C7006E91FB /* ORKLoginStepViewController.h in Headers */,
BC13CE401B0666FD0044153C /* ORKResultPredicate.h in Headers */,
@@ -2632,13 +2832,17 @@
86C40D1C1A8D7C5C00081FAC /* ORKFormSectionTitleLabel.h in Headers */,
86C40CBC1A8D7C5C00081FAC /* UITouch+ORKJSONDictionary.h in Headers */,
241A2E871B94FD8800ED3B39 /* ORKPasscodeStepViewController_Internal.h in Headers */,
FF5051ED1D668FF80065E677 /* ORKPageStep_Private.h in Headers */,
86C40D741A8D7C5C00081FAC /* ORKScaleRangeLabel.h in Headers */,
86C40DDE1A8D7C5C00081FAC /* ORKVerticalContainerView.h in Headers */,
9550E67C1D58DD2000C691B8 /* ORKTouchAnywhereStepViewController.h in Headers */,
BC94EF311E962F7400143081 /* ORKDeprecated.h in Headers */,
86C40CB01A8D7C5C00081FAC /* ORKRecorder_Internal.h in Headers */,
86C40E101A8D7C5C00081FAC /* ORKConsentSceneViewController.h in Headers */,
86C40DAA1A8D7C5C00081FAC /* ORKSurveyAnswerCellForNumber.h in Headers */,
10864C9E1B27146B000F4158 /* ORKPSATStep.h in Headers */,
86C40D6E1A8D7C5C00081FAC /* ORKResult_Private.h in Headers */,
781D54121DF886AB00223305 /* ORKTrailmakingStep.h in Headers */,
86C40D161A8D7C5C00081FAC /* ORKErrors.h in Headers */,
866DA5291D63D04700C9AF3F /* ORKOperation.h in Headers */,
861D11B51AA7D073003C98A7 /* ORKTextChoiceCellGroup.h in Headers */,
@@ -2646,7 +2850,6 @@
147503B91AEE807C004B17F3 /* ORKToneAudiometryStep.h in Headers */,
106FF2A21B665B86004EACF2 /* ORKHolePegTestPlaceStepViewController.h in Headers */,
24A4DA101B8D0F21009C797A /* ORKPasscodeStepView.h in Headers */,
86C40C9A1A8D7C5C00081FAC /* ORKDataLogger_Private.h in Headers */,
2489F7B11D65214D008DEF20 /* ORKVideoCaptureStep.h in Headers */,
861D11AD1AA7951F003C98A7 /* ORKChoiceAnswerFormatHelper.h in Headers */,
86C40C461A8D7C5C00081FAC /* ORKSpatialSpanMemoryStepViewController.h in Headers */,
@@ -2708,12 +2911,15 @@
attributes = {
CLASSPREFIX = ORK;
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0800;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = researchkit.org;
TargetAttributes = {
86CC8E991AC09332001CCD89 = {
CreatedOnToolsVersion = 6.2;
};
B183A4731A8535D100C76870 = {
LastSwiftMigration = 0900;
};
B18FF3A41A9FE25700C0C3B0 = {
CreatedOnToolsVersion = 7.0;
};
@@ -2888,14 +3094,17 @@
86C40CB61A8D7C5C00081FAC /* ORKTouchRecorder.m in Sources */,
B12EA0161B0D73A500F9F554 /* ORKToneAudiometryPracticeStep.m in Sources */,
CBD34A5B1BB207FC00F204EA /* ORKSurveyAnswerCellForLocation.m in Sources */,
959A2C011D68B9DA00841B04 /* ORKRangeOfMotionStepViewController.m in Sources */,
861D2AF11B8409D9008C4CD0 /* ORKTimedWalkContentView.m in Sources */,
86C40DC41A8D7C5C00081FAC /* ORKTapCountLabel.m in Sources */,
25ECC0A01AFBD92D00F3D63B /* ORKReactionTimeContentView.m in Sources */,
86C40D4C1A8D7C5C00081FAC /* ORKLabel.m in Sources */,
86C40C9E1A8D7C5C00081FAC /* ORKDeviceMotionRecorder.m in Sources */,
FFF65AB91E318F2D0043FB40 /* ORKMultipleValuePicker.m in Sources */,
86C40D961A8D7C5C00081FAC /* ORKStepViewController.m in Sources */,
2489F7B21D65214D008DEF20 /* ORKVideoCaptureStep.m in Sources */,
86C40DF81A8D7C5C00081FAC /* ORKSignatureStepViewController.m in Sources */,
959A2BFD1D68B98700841B04 /* ORKRangeOfMotionStep.m in Sources */,
BCB6E6531B7D533B000D5B34 /* ORKPieChartLegendCell.m in Sources */,
866DA52A1D63D04700C9AF3F /* ORKOperation.m in Sources */,
86C40D8C1A8D7C5C00081FAC /* ORKSkin.m in Sources */,
@@ -2943,8 +3152,11 @@
BC1C032D1CA301E300869355 /* ORKHeightPicker.m in Sources */,
86C40CF81A8D7C5C00081FAC /* ORKBorderedButton.m in Sources */,
86C40E201A8D7C5C00081FAC /* ORKConsentSignature.m in Sources */,
BF1D43861D4904C6007EE90B /* ORKVideoInstructionStep.m in Sources */,
9550E67D1D58DD2000C691B8 /* ORKTouchAnywhereStepViewController.m in Sources */,
86C40C601A8D7C5C00081FAC /* ORKWalkingTaskStepViewController.m in Sources */,
BCD192E01B81240400FCC08A /* ORKPieChartPieView.m in Sources */,
959A2C0E1D68C91400841B04 /* ORKShoulderRangeOfMotionStep.m in Sources */,
866F86011A96CBF3007B282C /* ORKSurveyAnswerCell.m in Sources */,
86C40E321A8D7C5C00081FAC /* ORKVisualConsentStepViewController.m in Sources */,
10FF9AD01B79F5CE00ECB5B4 /* ORKHolePegTestRemoveContentView.m in Sources */,
@@ -2970,8 +3182,10 @@
BCB6E6671B7D535F000D5B34 /* ORKXAxisView.m in Sources */,
147503BC1AEE807C004B17F3 /* ORKToneAudiometryStepViewController.m in Sources */,
86AD910B1AB7AD1E00361FEB /* ORKNavigationContainerView.m in Sources */,
FFDDD84A1D3555EA00446806 /* ORKPageStep.m in Sources */,
865EA1631AB8DF750037C68E /* ORKDateTimePicker.m in Sources */,
866DA5241D63D04700C9AF3F /* ORKDataCollectionManager.m in Sources */,
9550E6741D58DBCF00C691B8 /* ORKTouchAnywhereStep.m in Sources */,
86C40C781A8D7C5C00081FAC /* HKSample+ORKJSONDictionary.m in Sources */,
86C40D421A8D7C5C00081FAC /* ORKInstructionStep.m in Sources */,
86C40C2C1A8D7C5C00081FAC /* ORKFitnessContentView.m in Sources */,
@@ -2981,6 +3195,7 @@
86C40C241A8D7C5C00081FAC /* ORKCountdownStep.m in Sources */,
BCB6E65C1B7D534C000D5B34 /* ORKDiscreteGraphChartView.m in Sources */,
86C40CA21A8D7C5C00081FAC /* ORKHealthQuantityTypeRecorder.m in Sources */,
95E11E561D73396300BF865B /* ORKShoulderRangeOfMotionStepViewController.m in Sources */,
86C40DC01A8D7C5C00081FAC /* ORKTableViewCell.m in Sources */,
24A4DA111B8D0F21009C797A /* ORKPasscodeStepView.m in Sources */,
BC41942A1AE8453A00073D6B /* ORKObserver.m in Sources */,
@@ -2990,6 +3205,7 @@
86C40D7E1A8D7C5C00081FAC /* ORKScaleValueLabel.m in Sources */,
B12EA01A1B0D76AD00F9F554 /* ORKToneAudiometryPracticeStepViewController.m in Sources */,
8056857A1C90C19500BF437A /* UIImage+ResearchKit.m in Sources */,
BC94EF321E962F7400143081 /* ORKDeprecated.m in Sources */,
86C40D901A8D7C5C00081FAC /* ORKStep.m in Sources */,
86C40D2E1A8D7C5C00081FAC /* ORKHeadlineLabel.m in Sources */,
FA7A9D341B0843A9005A2BEA /* ORKConsentSignatureFormatter.m in Sources */,
@@ -3021,6 +3237,7 @@
86C40DAC1A8D7C5C00081FAC /* ORKSurveyAnswerCellForNumber.m in Sources */,
86C40C541A8D7C5C00081FAC /* ORKTappingIntervalStep.m in Sources */,
86C40D6C1A8D7C5C00081FAC /* ORKResult.m in Sources */,
781D54151DF886AB00223305 /* ORKTrailmakingStepViewController.m in Sources */,
86C40CD21A8D7C5C00081FAC /* ORKInstructionStepView.m in Sources */,
10FF9AD81B7A045E00ECB5B4 /* ORKSeparatorView.m in Sources */,
86C40D181A8D7C5C00081FAC /* ORKErrors.m in Sources */,
@@ -3033,6 +3250,7 @@
24A4DA151B8D1115009C797A /* ORKPasscodeStep.m in Sources */,
86C40DEC1A8D7C5C00081FAC /* UIBarButtonItem+ORKBarButtonItem.m in Sources */,
106FF2AF1B6FACA8004EACF2 /* ORKDirectionView.m in Sources */,
BF1D438A1D4905FC007EE90B /* ORKVideoInstructionStepViewController.m in Sources */,
86C40CAA1A8D7C5C00081FAC /* ORKPedometerRecorder.m in Sources */,
BCA5C0361AEC05F20092AC8D /* ORKStepNavigationRule.m in Sources */,
106FF2A71B665CF5004EACF2 /* ORKHolePegTestPlaceContentView.m in Sources */,
@@ -3045,8 +3263,11 @@
86C40C3C1A8D7C5C00081FAC /* ORKSpatialSpanGameState.m in Sources */,
86C40CF41A8D7C5C00081FAC /* ORKBodyLabel.m in Sources */,
106FF29F1B663FCE004EACF2 /* ORKHolePegTestPlaceStep.m in Sources */,
FFAE71411DAEC66200AE82B4 /* ORKFootnoteLabel.m in Sources */,
86C40C941A8D7C5C00081FAC /* ORKAudioRecorder.m in Sources */,
FF5E3CCC1D23444400ECE4B7 /* ORKPageStepViewController.m in Sources */,
86C40C581A8D7C5C00081FAC /* ORKTappingIntervalStepViewController.m in Sources */,
BA0AA6971EAEC0B600671ACE /* ORKStroopStep.m in Sources */,
86C40E0E1A8D7C5C00081FAC /* ORKConsentReviewStepViewController.m in Sources */,
BF9155A01BDE8D7E007FA459 /* ORKReviewStepViewController.m in Sources */,
86C40E261A8D7C5C00081FAC /* ORKEAGLMoviePlayerView.m in Sources */,
@@ -3065,14 +3286,18 @@
86C40C8E1A8D7C5C00081FAC /* ORKActiveStepViewController.m in Sources */,
10864CA51B27146B000F4158 /* ORKPSATKeyboardView.m in Sources */,
86C40CE61A8D7C5C00081FAC /* ORKAnswerFormat.m in Sources */,
FF5424531DF1513B00A86918 /* ORKHealthAnswerFormat.swift in Sources */,
25ECC0961AFBD68300F3D63B /* ORKReactionTimeStep.m in Sources */,
BC13CE3A1B0660220044153C /* ORKNavigableOrderedTask.m in Sources */,
BA0AA6991EAEC0B600671ACE /* ORKStroopStepViewController.m in Sources */,
B11C54A11A9EF4A700265E61 /* ORKConsentSharingStepViewController.m in Sources */,
86C40DA81A8D7C5C00081FAC /* ORKSurveyAnswerCellForImageSelection.m in Sources */,
86C40CCE1A8D7C5C00081FAC /* ORKImageSelectionView.m in Sources */,
86C40D461A8D7C5C00081FAC /* ORKInstructionStepViewController.m in Sources */,
BCB6E6611B7D534C000D5B34 /* ORKLineGraphChartView.m in Sources */,
86C40C7C1A8D7C5C00081FAC /* ORKAccelerometerRecorder.m in Sources */,
781D54111DF886AB00223305 /* ORKTrailmakingContentView.m in Sources */,
FF5051F11D66908C0065E677 /* ORKNavigablePageStep.m in Sources */,
86C40C861A8D7C5C00081FAC /* ORKActiveStepTimer.m in Sources */,
242C9E061BBDFDAC0088B7F4 /* ORKVerificationStep.m in Sources */,
B11C549B1A9EEF8800265E61 /* ORKConsentSharingStep.m in Sources */,
@@ -3087,7 +3312,9 @@
86C40DF41A8D7C5C00081FAC /* ORKConsentReviewController.m in Sources */,
242C9E121BBE06DE0088B7F4 /* ORKVerificationStepView.m in Sources */,
2489F7B01D65214D008DEF20 /* ORKVideoCaptureCameraPreviewView.m in Sources */,
BA0AA6951EAEC0B600671ACE /* ORKStroopContentView.m in Sources */,
147503BA1AEE807C004B17F3 /* ORKToneAudiometryStep.m in Sources */,
781D54131DF886AB00223305 /* ORKTrailmakingStep.m in Sources */,
FA7A9D301B083DD3005A2BEA /* ORKConsentSectionFormatter.m in Sources */,
86C40D2A1A8D7C5C00081FAC /* ORKFormTextView.m in Sources */,
242C9E0E1BBE03F90088B7F4 /* ORKVerificationStepViewController.m in Sources */,
@@ -3183,8 +3410,11 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
@@ -3204,7 +3434,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = 1;
@@ -3225,8 +3455,11 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
@@ -3240,8 +3473,9 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = 1;
TOOLCHAINS = default;
VALIDATE_PRODUCT = YES;
@@ -3296,7 +3530,7 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEAD_CODE_STRIPPING = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -3314,13 +3548,14 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = ResearchKit/module.modulemap;
MODULEMAP_FILE = ResearchKit/ResearchKit.modulemap;
MTL_ENABLE_DEBUG_INFO = YES;
PRODUCT_BUNDLE_IDENTIFIER = "org.researchkit.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = ResearchKit;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
@@ -3331,7 +3566,7 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEAD_CODE_STRIPPING = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -3346,13 +3581,14 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = ResearchKit/module.modulemap;
MODULEMAP_FILE = ResearchKit/ResearchKit.modulemap;
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = "org.researchkit.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = ResearchKit;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -46,7 +46,7 @@
NSDate *timestamp = self.timestamp;
CLFloor *floor = self.floor;
NSMutableDictionary *dictionary = [@{@"timestamp": ORKStringFromDateISO8601(timestamp)} mutableCopy];
NSMutableDictionary *dictionary = [@{ @"timestamp": ORKStringFromDateISO8601(timestamp) } mutableCopy];
if (horizAccuracy >= 0) {
dictionary[@"coordinate"] = @{ @"latitude": [NSDecimalNumber numberWithDouble:coord.latitude],
@@ -35,7 +35,7 @@
@implementation CMAccelerometerData (ORKJSONDictionary)
- (NSDictionary *)ork_JSONDictionary {
NSDictionary *dictionary = @{@"timestamp": [NSDecimalNumber numberWithDouble:self.timestamp],
NSDictionary *dictionary = @{ @"timestamp": [NSDecimalNumber numberWithDouble:self.timestamp],
@"x": [NSDecimalNumber numberWithDouble:self.acceleration.x],
@"y": [NSDecimalNumber numberWithDouble:self.acceleration.y],
@"z": [NSDecimalNumber numberWithDouble:self.acceleration.z]
@@ -72,6 +72,7 @@ static NSArray *activityArray(CMMotionActivity *activity) {
static NSString *const ActivityKey = @"activity";
static NSString *const ConfidenceKey = @"confidence";
@implementation CMMotionActivity (ORKJSONDictionary)
- (NSDictionary *)ork_JSONDictionary {
@@ -39,10 +39,8 @@
@implementation CMPedometerData (ORKJSONDictionary)
- (NSDictionary *)ork_JSONDictionary {
NSMutableDictionary *dictionary = [@{@"startDate": ORKStringFromDateISO8601(self.startDate),
@"endDate": ORKStringFromDateISO8601(self.endDate)
} mutableCopy];
for (NSString *key in @[@"numberOfSteps", @"distance", @"floorsAscended", @"floorsDescended"]) {
NSMutableDictionary *dictionary = [@{ @"startDate": ORKStringFromDateISO8601(self.startDate), @"endDate": ORKStringFromDateISO8601(self.endDate) } mutableCopy];
for (NSString *key in @[ @"numberOfSteps", @"distance", @"floorsAscended", @"floorsDescended" ]) {
[dictionary setValue:[self valueForKey:key] forKey:key];
}
return dictionary;
@@ -59,7 +59,7 @@ ORK_CLASS_AVAILABLE
@return An initialized accelerometer recorder.
*/
- (instancetype)initWithIdentifier:(NSString *)identifer
- (instancetype)initWithIdentifier:(NSString *)identifier
frequency:(double)frequency
step:(nullable ORKStep *)step
outputDirectory:(nullable NSURL *)outputDirectory;
@@ -73,7 +73,7 @@
}
- (void)setFrequency:(double)frequency {
if (frequency <=0) {
if (frequency <= 0) {
_frequency = 1;
} else {
_frequency = frequency;
-12
View File
@@ -214,18 +214,6 @@ The default value of this property is `NO`.
*/
@property (nonatomic, copy, nullable) NSArray<ORKRecorderConfiguration *> *recorderConfigurations;
/**
The set of HealthKit types the step requests for reading. (read-only)
The task view controller uses this set of types when constructing a list of
all the HealthKit types required by all the steps in a task, so that it can
present the HealthKit access dialog just once during that task.
By default, the property scans the recorders and collates the HealthKit
types the recorders require. Subclasses may override this implementation.
*/
@property (nonatomic, readonly, nullable) NSSet<HKObjectType *> *requestedHealthKitTypesForReading;
@end
NS_ASSUME_NONNULL_END
@@ -47,6 +47,7 @@ static NSTimeInterval timeIntervalFromMachTime(uint64_t delta) {
return elapsedNano * 1.0 / NSEC_PER_SEC;
}
@implementation ORKActiveStepTimer {
uint64_t _startTime;
NSTimeInterval _preExistingRuntime;
@@ -97,6 +97,7 @@
}
- (ORKActiveStep *)activeStep {
NSAssert(self.step == nil || [self.step isKindOfClass:[ORKActiveStep class]], @"Step should be a subclass of an ORKActiveStep");
return (ORKActiveStep *)self.step;
}
@@ -210,7 +211,9 @@
- (ORKStepResult *)result {
ORKStepResult *sResult = [super result];
sResult.results = _recorderResults;
if (_recorderResults) {
sResult.results = [sResult.results arrayByAddingObjectsFromArray:_recorderResults] ? : _recorderResults;
}
return sResult;
}
@@ -436,7 +439,7 @@
BOOL isHalfway = !_hasSpokenHalfwayCountdown && timer.runtime > timer.duration / 2.0;
if (!finished && self.activeStep.shouldSpeakRemainingTimeAtHalfway && !UIAccessibilityIsVoiceOverRunning() && isHalfway) {
_hasSpokenHalfwayCountdown = YES;
NSString *text = [NSString stringWithFormat:ORKLocalizedString(@"COUNTDOWN_SPOKEN_REMAINING_%@", nil), @(countDownValue)];
NSString *text = [NSString localizedStringWithFormat:ORKLocalizedString(@"COUNTDOWN_SPOKEN_REMAINING_%@", nil), @(countDownValue)];
[voice speakText:text];
}
}
@@ -61,6 +61,7 @@ static const CGFloat GraphViewRedZoneHeight = 25;
static const CGFloat ValueLineWidth = 4.5;
static const CGFloat ValueLineMargin = 1.5;
@implementation ORKAudioGraphView
- (instancetype)initWithFrame:(CGRect)frame {
@@ -69,7 +70,7 @@ static const CGFloat ValueLineMargin = 1.5;
[self setUpConstraints];
#if TARGET_IPHONE_SIMULATOR
_values = @[@(0.2),@(0.6),@(0.55), @(0.1), @(0.75), @(0.7)];
_values = @[ @(0.2), @(0.6), @(0.55), @(0.1), @(0.75), @(0.7) ];
#endif
}
return self;
+1 -1
View File
@@ -52,9 +52,9 @@
#import "ORKAudioGenerator.h"
@import AudioToolbox;
@interface ORKAudioGenerator () {
@public
AudioComponentInstance _toneUnit;
@@ -38,6 +38,15 @@ NS_ASSUME_NONNULL_BEGIN
ORK_CLASS_AVAILABLE
@interface ORKAudioLevelNavigationRule : ORKStepNavigationRule
/*
The `init` and `new` methods are unavailable.
`ORKStepNavigationRule` classes should be initialized with custom designated initializers on each
subclass.
*/
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
/**
Returns an initialized direct-step navigation rule using the specified destination step identifier.
@@ -58,6 +58,14 @@ Float32 const VolumeClamp = 60.0;
@implementation ORKAudioLevelNavigationRule
+ (instancetype)new {
ORKThrowMethodUnavailableException();
}
- (instancetype)init {
ORKThrowMethodUnavailableException();
}
- (instancetype)initWithAudioLevelStepIdentifier:(NSString *)audioLevelStepIdentifier
destinationStepIdentifier:(NSString *)destinationStepIdentifier
recordingSettings:(NSDictionary *)recordingSettings
@@ -65,7 +73,7 @@ Float32 const VolumeClamp = 60.0;
ORKThrowInvalidArgumentExceptionIfNil(audioLevelStepIdentifier);
ORKThrowInvalidArgumentExceptionIfNil(destinationStepIdentifier);
ORKThrowInvalidArgumentExceptionIfNil(recordingSettings);
self = [super init_ork];
self = [super init];
if (self) {
_audioLevelStepIdentifier = [audioLevelStepIdentifier copy];
_destinationStepIdentifier = [destinationStepIdentifier copy];
+1
View File
@@ -48,6 +48,7 @@
self = [super initWithIdentifier:identifier];
if (self) {
self.shouldShowDefaultTimer = NO;
self.shouldStartTimerAutomatically = YES;
}
return self;
}
@@ -91,11 +91,6 @@
self.activeStepView.activeCustomView = _audioContentView;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self start];
}
- (void)audioRecorderDidChange {
_audioRecorder.audioRecorder.meteringEnabled = YES;
[self setAvAudioRecorder:_audioRecorder.audioRecorder];
@@ -187,7 +182,7 @@
_avAudioRecorder = recorder;
}
- (void) recorder:(ORKRecorder *)recorder didFailWithError:(NSError *)error {
- (void)recorder:(ORKRecorder *)recorder didFailWithError:(NSError *)error {
[super recorder:recorder didFailWithError:error];
_audioRecorderError = error;
_audioContentView.failed = YES;
@@ -52,6 +52,7 @@
@end
@implementation ORKCountDownViewLabel
+ (UIFont *)defaultFont {
return ORKThinFontWithSize(56);
@@ -178,8 +179,8 @@ static const CGFloat ProgressIndicatorOuterMargin = 1.0;
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"strokeEnd"];
animation.duration = duration * 2;
animation.removedOnCompletion = YES;
animation.values = @[@(1.0), @(0.0), @(0.0)];
animation.keyTimes = @[@(0.0), @(0.5), @(1.0)];
animation.values = @[ @(1.0), @(0.0), @(0.0) ];
animation.keyTimes = @[ @(0.0), @(0.5), @(1.0) ];
animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[_circleLayer addAnimation:animation forKey:@"drawCircleAnimation"];
}
+13 -13
View File
@@ -359,7 +359,7 @@ static NSInteger _ORKJSON_terminatorLength = 0;
* before writing. When writing, we write a separator (if needed), the JSON
* object being appended, and the footer bytes.
*/
- (BOOL)appendObjects:(NSArray *)objects fileHandle:(NSFileHandle *)fileHandle error:(NSError **)error {
- (BOOL)appendObjects:(NSArray *)objects fileHandle:(NSFileHandle *)fileHandle error:(NSError * __autoreleasing *)error {
if (!fileHandle) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Filehandle is nil" userInfo:nil];
}
@@ -571,7 +571,7 @@ static NSInteger _ORKJSON_terminatorLength = 0;
return _currentFileHandle;
}
- (BOOL)enumerateLogs:(void (^)(NSURL *logFileUrl, BOOL *stop))block error:(NSError **)error {
- (BOOL)enumerateLogs:(void (^)(NSURL *logFileUrl, BOOL *stop))block error:(NSError * __autoreleasing *)error {
if (!block) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Block parameter is required" userInfo:nil];
}
@@ -583,7 +583,7 @@ static NSInteger _ORKJSON_terminatorLength = 0;
return success;
}
- (BOOL)enumerateLogsUploaded:(BOOL)uploaded block:(void (^)(NSURL *logFileUrl, BOOL *stop))block error:(NSError **)error {
- (BOOL)enumerateLogsUploaded:(BOOL)uploaded block:(void (^)(NSURL *logFileUrl, BOOL *stop))block error:(NSError * __autoreleasing *)error {
if (!block) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Block parameter is required" userInfo:nil];
}
@@ -603,7 +603,7 @@ static NSInteger _ORKJSON_terminatorLength = 0;
return [self enumerateLogsUploaded:YES block:block error:error];
}
- (BOOL)append:(id)object error:(NSError **)error {
- (BOOL)append:(id)object error:(NSError * __autoreleasing *)error {
if (!object) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Nil object" userInfo:nil];
}
@@ -614,7 +614,7 @@ static NSInteger _ORKJSON_terminatorLength = 0;
return success;
}
- (BOOL)appendObjects:(NSArray *)objects error:(NSError **)error {
- (BOOL)appendObjects:(NSArray *)objects error:(NSError * __autoreleasing *)error {
if (!objects.count) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Empty array" userInfo:nil];
}
@@ -625,7 +625,7 @@ static NSInteger _ORKJSON_terminatorLength = 0;
return success;
}
- (BOOL)markFileUploaded:(BOOL)uploaded atURL:(NSURL *)url error:(NSError **)error {
- (BOOL)markFileUploaded:(BOOL)uploaded atURL:(NSURL *)url error:(NSError * __autoreleasing *)error {
__block BOOL success = NO;
dispatch_sync(_queue, ^{
success = [self queue_markFileUploaded:uploaded atURL:url error:error];
@@ -633,7 +633,7 @@ static NSInteger _ORKJSON_terminatorLength = 0;
return success;
}
- (BOOL)removeUploadedFiles:(NSArray<NSURL *> *)fileURLs withError:(NSError **)error {
- (BOOL)removeUploadedFiles:(NSArray<NSURL *> *)fileURLs withError:(NSError * __autoreleasing *)error {
__block BOOL success = NO;
dispatch_sync(_queue, ^{
success = [self queue_removeUploadedFiles:fileURLs withError:error];
@@ -641,7 +641,7 @@ static NSInteger _ORKJSON_terminatorLength = 0;
return success;
}
- (BOOL)removeAllFilesWithError:(NSError **)error {
- (BOOL)removeAllFilesWithError:(NSError * __autoreleasing *)error {
__block BOOL success = NO;
dispatch_sync(_queue, ^{
success = [self queue_removeAllFilesWithError:error];
@@ -983,7 +983,7 @@ static NSInteger _ORKJSON_terminatorLength = 0;
return success;
}
- (BOOL)queue_removeAllFilesWithError:(NSError **)error {
- (BOOL)queue_removeAllFilesWithError:(NSError * __autoreleasing *)error {
[_currentFileHandle closeFile];
_currentFileHandle = nil;
@@ -1221,7 +1221,7 @@ static NSString *const LoggerConfigurationsKey = @"loggers";
return success;
}
- (BOOL)enumerateLogsNeedingUpload:(void (^)(ORKDataLogger *dataLogger, NSURL *logFileUrl, BOOL *stop))block error:(NSError **)error {
- (BOOL)enumerateLogsNeedingUpload:(void (^)(ORKDataLogger *dataLogger, NSURL *logFileUrl, BOOL *stop))block error:(NSError * __autoreleasing *)error {
if (!block) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Block argument required" userInfo:nil];
}
@@ -1256,7 +1256,7 @@ static NSString *const LoggerConfigurationsKey = @"loggers";
return success;
}
- (BOOL)removeUploadedFiles:(NSArray<NSURL *> *)fileURLs error:(NSError **)error {
- (BOOL)removeUploadedFiles:(NSArray<NSURL *> *)fileURLs error:(NSError * __autoreleasing *)error {
__block BOOL success = YES;
dispatch_sync(_queue, ^{
@@ -1288,7 +1288,7 @@ static NSString *const LoggerConfigurationsKey = @"loggers";
return success;
}
- (BOOL)unmarkUploadedFiles:(NSArray<NSURL *> *)fileURLs error:(NSError **)error {
- (BOOL)unmarkUploadedFiles:(NSArray<NSURL *> *)fileURLs error:(NSError * __autoreleasing *)error {
__block BOOL success = YES;
dispatch_sync(_queue, ^{
success = [self queue_unmarkUploadedFiles:fileURLs error:error];
@@ -1353,7 +1353,7 @@ static NSString *const LoggerConfigurationsKey = @"loggers";
return (totalBytes <= bytes);
}
- (BOOL)removeOldAndUploadedLogsToThreshold:(unsigned long long)bytes error:(NSError **)error {
- (BOOL)removeOldAndUploadedLogsToThreshold:(unsigned long long)bytes error:(NSError * __autoreleasing *)error {
__block BOOL success = YES;
dispatch_sync(_queue, ^{
success = [self queue_removeOldAndUploadedLogsToThreshold:bytes error:error];
@@ -319,7 +319,7 @@
HKQuantity *quantity = [HKQuantity quantityWithUnit:[HKUnit meterUnit] doubleValue:displayDistance];
distanceString = [_lengthFormatter.numberFormatter stringFromNumber:@([quantity doubleValueForUnit:hkUnit]*conversionFactor)];
[self distanceView].title = [NSString stringWithFormat:ORKLocalizedString(@"FITNESS_DISTANCE_TITLE_FORMAT", nil), unitString];
[self distanceView].title = [NSString localizedStringWithFormat:ORKLocalizedString(@"FITNESS_DISTANCE_TITLE_FORMAT", nil), unitString];
[self distanceView].value = distanceString;
}
@@ -47,7 +47,7 @@
#import "ORKHelpers_Internal.h"
@interface ORKFitnessStepViewController () <ORKHealthQuantityTypeRecorderDelegate,ORKPedometerRecorderDelegate> {
@interface ORKFitnessStepViewController () <ORKHealthQuantityTypeRecorderDelegate, ORKPedometerRecorderDelegate> {
NSInteger _intendedSteps;
ORKFitnessContentView *_contentView;
NSNumberFormatter *_hrFormatter;
@@ -186,6 +186,7 @@ static const NSInteger _HealthAnchoredQueryLimit = 100;
else {
NSAssert(NO, @"Could not instantiate an HKAnchoredObjectQuery.");
}
[_healthStore executeQuery:anchoredQuery];
}
@@ -41,7 +41,7 @@ ORK_CLASS_AVAILABLE
@property (nonatomic, assign) ORKBodySagittal movingDirection;
@property (nonatomic, assign, getter = isDominantHandTested) BOOL dominantHandTested;
@property (nonatomic, assign) int numberOfPegs;
@property (nonatomic, assign) NSInteger numberOfPegs;
@property (nonatomic, assign) double threshold;
@property (nonatomic, assign, getter = isRotated) BOOL rotated;
@@ -30,8 +30,8 @@
#import "ORKHolePegTestPlaceStep.h"
#import "ORKHolePegTestPlaceStepViewController.h"
#import "ORKHelpers_Internal.h"
@implementation ORKHolePegTestPlaceStep
@@ -82,4 +82,55 @@
return NO;
}
+ (BOOL)supportsSecureCoding {
return YES;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
ORK_DECODE_ENUM(aDecoder, movingDirection);
ORK_DECODE_BOOL(aDecoder, dominantHandTested);
ORK_DECODE_INTEGER(aDecoder, numberOfPegs);
ORK_DECODE_DOUBLE(aDecoder, threshold);
ORK_DECODE_BOOL(aDecoder, rotated);
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[super encodeWithCoder:aCoder];
ORK_ENCODE_ENUM(aCoder, movingDirection);
ORK_ENCODE_BOOL(aCoder, dominantHandTested);
ORK_ENCODE_INTEGER(aCoder, numberOfPegs);
ORK_ENCODE_DOUBLE(aCoder, threshold);
ORK_ENCODE_BOOL(aCoder, rotated);
}
- (instancetype)copyWithZone:(NSZone *)zone {
__typeof(self) step = [super copyWithZone:zone];
step.movingDirection = self.movingDirection;
step.dominantHandTested = self.dominantHandTested;
step.numberOfPegs = self.numberOfPegs;
step.threshold = self.threshold;
step.rotated = self.rotated;
return step;
}
- (NSUInteger)hash {
return [super hash] ^ self.movingDirection ^ self.dominantHandTested ^ self.numberOfPegs ^ (NSInteger)(self.threshold * 100) ^ self.rotated;
}
- (BOOL)isEqual:(id)object {
BOOL isParentSame = [super isEqual:object];
__typeof(self) castObject = object;
return (isParentSame &&
(self.movingDirection == castObject.movingDirection) &&
(self.dominantHandTested == castObject.dominantHandTested) &&
(self.numberOfPegs == castObject.numberOfPegs) &&
(self.threshold == castObject.threshold) &&
(self.rotated == castObject.rotated));
}
@end
@@ -41,7 +41,7 @@ ORK_CLASS_AVAILABLE
@property (nonatomic, assign) ORKBodySagittal movingDirection;
@property (nonatomic, assign, getter = isDominantHandTested) BOOL dominantHandTested;
@property (nonatomic, assign) int numberOfPegs;
@property (nonatomic, assign) NSInteger numberOfPegs;
@property (nonatomic, assign) double threshold;
@end
@@ -33,6 +33,8 @@
#import "ORKHolePegTestRemoveStepViewController.h"
#import "ORKHelpers_Internal.h"
@implementation ORKHolePegTestRemoveStep
@@ -82,4 +84,51 @@
return NO;
}
+ (BOOL)supportsSecureCoding {
return YES;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
ORK_DECODE_ENUM(aDecoder, movingDirection);
ORK_DECODE_BOOL(aDecoder, dominantHandTested);
ORK_DECODE_INTEGER(aDecoder, numberOfPegs);
ORK_DECODE_DOUBLE(aDecoder, threshold);
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[super encodeWithCoder:aCoder];
ORK_ENCODE_ENUM(aCoder, movingDirection);
ORK_ENCODE_BOOL(aCoder, dominantHandTested);
ORK_ENCODE_INTEGER(aCoder, numberOfPegs);
ORK_ENCODE_DOUBLE(aCoder, threshold);
}
- (instancetype)copyWithZone:(NSZone *)zone {
__typeof(self) step = [super copyWithZone:zone];
step.movingDirection = self.movingDirection;
step.dominantHandTested = self.dominantHandTested;
step.numberOfPegs = self.numberOfPegs;
step.threshold = self.threshold;
return step;
}
- (NSUInteger)hash {
return [super hash] ^ self.movingDirection ^ self.dominantHandTested ^ self.numberOfPegs ^ (NSInteger)(self.threshold * 100);
}
- (BOOL)isEqual:(id)object {
BOOL isParentSame = [super isEqual:object];
__typeof(self) castObject = object;
return (isParentSame &&
(self.movingDirection == castObject.movingDirection) &&
(self.dominantHandTested == castObject.dominantHandTested) &&
(self.numberOfPegs == castObject.numberOfPegs) &&
(self.threshold == castObject.threshold));
}
@end
+49
View File
@@ -33,6 +33,8 @@
#import "ORKPSATStepViewController.h"
#import "ORKHelpers_Internal.h"
@implementation ORKPSATStep
@@ -91,4 +93,51 @@
return NO;
}
+ (BOOL)supportsSecureCoding {
return YES;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
ORK_DECODE_ENUM(aDecoder, presentationMode);
ORK_DECODE_DOUBLE(aDecoder, interStimulusInterval);
ORK_DECODE_DOUBLE(aDecoder, stimulusDuration);
ORK_DECODE_INTEGER(aDecoder, seriesLength);
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[super encodeWithCoder:aCoder];
ORK_ENCODE_ENUM(aCoder, presentationMode);
ORK_ENCODE_DOUBLE(aCoder, interStimulusInterval);
ORK_ENCODE_DOUBLE(aCoder, stimulusDuration);
ORK_ENCODE_INTEGER(aCoder, seriesLength);
}
- (instancetype)copyWithZone:(NSZone *)zone {
ORKPSATStep *step = [super copyWithZone:zone];
step.presentationMode = self.presentationMode;
step.interStimulusInterval = self.interStimulusInterval;
step.stimulusDuration = self.stimulusDuration;
step.seriesLength = self.seriesLength;
return step;
}
- (NSUInteger)hash {
return [super hash] ^ self.presentationMode ^ (NSInteger)(self.interStimulusInterval*100) ^ (NSInteger)(self.stimulusDuration*100) ^ self.seriesLength;
}
- (BOOL)isEqual:(id)object {
BOOL isParentSame = [super isEqual:object];
__typeof(self) castObject = object;
return (isParentSame &&
(self.presentationMode == castObject.presentationMode) &&
(self.interStimulusInterval == castObject.interStimulusInterval) &&
(self.stimulusDuration == castObject.stimulusDuration) &&
(self.seriesLength == castObject.seriesLength));
}
@end
@@ -58,6 +58,7 @@
@end
@implementation ORKPSATStepViewController
- (instancetype)initWithStep:(ORKStep *)step {
@@ -71,6 +72,7 @@
}
- (ORKPSATStep *)psatStep {
NSAssert(self.step == nil || [self.step isKindOfClass:[ORKPSATStep class]], @"Step class must be subclass of ORKPSATStep.");
return (ORKPSATStep *)self.step;
}
@@ -0,0 +1,52 @@
/*
Copyright (c) 2016, Darren Levy. 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;
#import <ResearchKit/ORKDefines.h>
#import <ResearchKit/ORKActiveStep.h>
#import <ResearchKit/ORKOrderedTask.h>
NS_ASSUME_NONNULL_BEGIN
/**
The `ORKRangeOfMotionStep` class represents a step that takes a range of motion measurement.
*/
ORK_CLASS_AVAILABLE
@interface ORKRangeOfMotionStep : ORKActiveStep
@property (nonatomic, assign) ORKPredefinedTaskLimbOption limbOption; //The left and/or right limb to be tested during the task
- (instancetype)initWithIdentifier:(NSString *)identifier limbOption:(ORKPredefinedTaskLimbOption)limbOption;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,101 @@
/*
Copyright (c) 2016, Darren Levy. 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 "ORKRangeOfMotionStep.h"
#import "ORKRangeOfMotionStepViewController.h"
#import "ORKHelpers_Internal.h"
@implementation ORKRangeOfMotionStep
+ (Class)stepViewControllerClass {
return [ORKRangeOfMotionStepViewController class];
}
- (instancetype)initWithIdentifier:(NSString *)identifier limbOption:(ORKPredefinedTaskLimbOption)limbOption {
self = [super initWithIdentifier:identifier];
if (self) {
self.shouldVibrateOnStart = YES;
self.shouldPlaySoundOnStart = YES;
self.shouldVibrateOnFinish = YES;
self.shouldPlaySoundOnFinish = YES;
self.shouldContinueOnFinish = YES;
self.shouldStartTimerAutomatically = YES;
self.limbOption = limbOption;
}
return self;
}
- (void)validateParameters {
[super validateParameters];
if (self.limbOption != ORKPredefinedTaskLimbOptionLeft && self.limbOption != ORKPredefinedTaskLimbOptionRight) {
@throw [NSException exceptionWithName:NSInvalidArgumentException
reason:ORKLocalizedString(@"LIMB_OPTION_LEFT_OR_RIGHT_ERROR", nil)
userInfo:nil];
}
}
- (BOOL)startsFinished {
return NO;
}
+ (BOOL)supportsSecureCoding {
return YES;
}
- (instancetype)copyWithZone:(NSZone *)zone {
ORKRangeOfMotionStep *step = [super copyWithZone:zone];
step.limbOption = self.limbOption;
return step;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
ORK_DECODE_INTEGER(aDecoder, limbOption);
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[super encodeWithCoder:aCoder];
ORK_ENCODE_INTEGER(aCoder, limbOption);
}
- (BOOL)isEqual:(id)object {
BOOL isParentSame = [super isEqual:object];
__typeof(self) castObject = object;
return (isParentSame && (self.limbOption == castObject.limbOption));
}
@end
@@ -0,0 +1,50 @@
/*
Copyright (c) 2016, Darren Levy. 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 <ResearchKit/ResearchKit.h>
#import <CoreMotion/CMDeviceMotion.h>
NS_ASSUME_NONNULL_BEGIN
/**
This class is used by the `ORKRangeOfMotionStep.` Its result corresponds to the device's orientation
as recorded by CoreMotion.
*/
ORK_CLASS_AVAILABLE
@interface ORKRangeOfMotionStepViewController : ORKActiveStepViewController {
double _flexedAngle;
double _rangeOfMotionAngle;
}
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,216 @@
/*
Copyright (c) 2016, Darren Levy. 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 "ORKRangeOfMotionStepViewController.h"
#import "ORKCustomStepView_Internal.h"
#import "ORKHelpers_Internal.h"
#import "ORKActiveStepViewController_Internal.h"
#import "ORKStepViewController_Internal.h"
#import "ORKVerticalContainerView_Internal.h"
#import "ORKDeviceMotionRecorder.h"
#import "ORKActiveStepView.h"
#import "ORKProgressView.h"
#import "ORKSkin.h"
#define radiansToDegrees(radians) ((radians) * 180.0 / M_PI)
#define allOrientationsForPitch(x, w, y, z) (atan2(2.0 * (x*w + y*z), 1.0 - 2.0 * (x*x + z*z)))
@interface ORKRangeOfMotionContentView : ORKActiveStepCustomView {
NSLayoutConstraint *_topConstraint;
}
@property (nonatomic, strong, readonly) ORKProgressView *progressView;
@end
@implementation ORKRangeOfMotionContentView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_progressView = [ORKProgressView new];
_progressView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_progressView];
[self setUpConstraints];
[self updateConstraintConstantsForWindow:self.window];
}
return self;
}
- (void)willMoveToWindow:(UIWindow *)newWindow {
[super willMoveToWindow:newWindow];
[self updateConstraintConstantsForWindow:newWindow];
}
- (void)setUpConstraints {
NSMutableArray *constraints = [NSMutableArray new];
NSDictionary *views = NSDictionaryOfVariableBindings(_progressView);
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_progressView]-(>=0)-|"
options:NSLayoutFormatAlignAllCenterX
metrics:nil
views:views]];
_topConstraint = [NSLayoutConstraint constraintWithItem:_progressView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0.0]; // constant will be set in updateConstraintConstantsForWindow:
[constraints addObject:_topConstraint];
[constraints addObject:[NSLayoutConstraint constraintWithItem:_progressView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[NSLayoutConstraint activateConstraints:constraints];
}
- (void)updateConstraintConstantsForWindow:(UIWindow *)window {
const CGFloat CaptionBaselineToProgressTop = 100;
const CGFloat CaptionBaselineToStepViewTop = ORKGetMetricForWindow(ORKScreenMetricLearnMoreBaselineToStepViewTop, window);
_topConstraint.constant = CaptionBaselineToProgressTop - CaptionBaselineToStepViewTop;
}
- (void)updateConstraints {
[self updateConstraintConstantsForWindow:self.window];
[super updateConstraints];
}
@end
@interface ORKRangeOfMotionStepViewController () <ORKDeviceMotionRecorderDelegate> {
ORKRangeOfMotionContentView *_contentView;
UITapGestureRecognizer *_gestureRecognizer;
CMAttitude *_referenceAttitude;
UIInterfaceOrientation _orientation;
double _highestAngle;
double _lowestAngle;
double _lastAngle;
}
@end
@implementation ORKRangeOfMotionStepViewController
- (void)viewDidLoad {
[super viewDidLoad];
_contentView = [ORKRangeOfMotionContentView new];
_contentView.translatesAutoresizingMaskIntoConstraints = NO;
self.activeStepView.activeCustomView = _contentView;
_gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[self.activeStepView addGestureRecognizer:_gestureRecognizer];
}
- (void)handleTap:(UIGestureRecognizer *)sender {
[self calculateAndSetFlexedAndExtendedAngles];
[self finish];
}
- (void)calculateAndSetFlexedAndExtendedAngles {
_flexedAngle = fabs([self getDeviceAngleInDegreesFromAttitude:_referenceAttitude]);
BOOL rangeOfMotionMoreThan180Degrees = _highestAngle > 175 && _lowestAngle < 175;
if (rangeOfMotionMoreThan180Degrees) {
_rangeOfMotionAngle = 360 - fabs(_lastAngle);
} else {
_rangeOfMotionAngle = fabs(_lastAngle);
}
}
#pragma mark - ORKDeviceMotionRecorderDelegate
- (void)deviceMotionRecorderDidUpdateWithMotion:(CMDeviceMotion *)motion {
if (!_referenceAttitude) {
_referenceAttitude = motion.attitude;
}
CMAttitude *currentAttitude = [motion.attitude copy];
[currentAttitude multiplyByInverseOfAttitude:_referenceAttitude];
double angle = [self getDeviceAngleInDegreesFromAttitude:currentAttitude];
if (angle > _highestAngle) {
_highestAngle = angle;
}
if (angle < _lowestAngle) {
_lowestAngle = angle;
}
_lastAngle = angle;
}
/*
When the device is in Portrait mode, we need to get the attitude's pitch
to determine the device's angle. attitude.pitch doesn't return all
orientations, so we use the attitude's quaternion to calculate the
angle.
*/
- (double)getDeviceAngleInDegreesFromAttitude:(CMAttitude *)attitude {
if (!_orientation) {
_orientation = [UIApplication sharedApplication].statusBarOrientation;
}
double angle;
if (UIInterfaceOrientationIsLandscape(_orientation)) {
angle = radiansToDegrees(attitude.roll);
} else {
double x = attitude.quaternion.x;
double w = attitude.quaternion.w;
double y = attitude.quaternion.y;
double z = attitude.quaternion.z;
angle = radiansToDegrees(allOrientationsForPitch(x, w, y, z));
}
return angle;
}
#pragma mark - ORKActiveTaskViewController
- (ORKResult *)result {
ORKStepResult *stepResult = [super result];
ORKRangeOfMotionResult *result = [[ORKRangeOfMotionResult alloc] initWithIdentifier:self.step.identifier];
result.flexed = _flexedAngle;
result.extended = result.flexed - _rangeOfMotionAngle;
stepResult.results = [self.addedResults arrayByAddingObject:result] ? : @[result];
return stepResult;
}
@end
@@ -35,6 +35,7 @@
#import "ORKReactionTimeContentView.h"
#import "ORKActiveStepViewController_Internal.h"
#import "ORKStepViewController_Internal.h"
#import "ORKReactionTimeStep.h"
#import "ORKResult.h"
@@ -106,7 +107,7 @@ static const NSTimeInterval OutcomeAnimationDuration = 0.3;
- (ORKStepResult *)result {
ORKStepResult *stepResult = [super result];
stepResult.results = _results;
stepResult.results = [self.addedResults arrayByAddingObjectsFromArray:_results] ? : _results;
return stepResult;
}
@@ -0,0 +1,42 @@
/*
Copyright (c) 2016, Darren Levy. 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 "ORKRangeOfMotionStep.h"
/**
The `ORKShoulderRangeOfMotionStep` class represents a step that takes a range of motion measurement
for either a left or right shoulder.
*/
ORK_CLASS_AVAILABLE
@interface ORKShoulderRangeOfMotionStep : ORKRangeOfMotionStep
@end
@@ -0,0 +1,43 @@
/*
Copyright (c) 2016, Darren Levy. 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 "ORKShoulderRangeOfMotionStep.h"
#import "ORKShoulderRangeOfMotionStepViewController.h"
#import "ORKHelpers_Internal.h"
@implementation ORKShoulderRangeOfMotionStep
+ (Class)stepViewControllerClass {
return [ORKShoulderRangeOfMotionStepViewController class];
}
@end
@@ -0,0 +1,42 @@
/*
Copyright (c) 2016, Darren Levy. 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 "ORKRangeOfMotionStepViewController.h"
/**
This class override its parent's result because here
a flex result of 0 degrees would mean the device is at a 90 degree angle.
*/
ORK_CLASS_AVAILABLE
@interface ORKShoulderRangeOfMotionStepViewController : ORKRangeOfMotionStepViewController
@end
@@ -0,0 +1,52 @@
/*
Copyright (c) 2016, Darren Levy. 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 "ORKShoulderRangeOfMotionStepViewController.h"
#import "ORKStepViewController_Internal.h"
@implementation ORKShoulderRangeOfMotionStepViewController
#pragma mark - ORKActiveTaskViewController
- (ORKResult *)result {
ORKStepResult *stepResult = [super result];
ORKRangeOfMotionResult *result = [[ORKRangeOfMotionResult alloc] initWithIdentifier:self.step.identifier];
result.flexed = 90.0 - _flexedAngle;
result.extended = result.flexed + _rangeOfMotionAngle;
stepResult.results = [self.addedResults arrayByAddingObject:result] ? : @[result];
return stepResult;
}
@end
@@ -203,7 +203,7 @@
_capitalizedPluralItemDescription = [ORKLocalizedString(@"SPATIAL_SPAN_MEMORY_TARGET_STANDALONE", nil) capitalizedStringWithLocale:[NSLocale currentLocale]];
countView.title = [NSString stringWithFormat:ORKLocalizedString(@"MEMORY_GAME_ITEM_COUNT_TITLE_%@", nil), _capitalizedPluralItemDescription];
countView.title = [NSString localizedStringWithFormat:ORKLocalizedString(@"MEMORY_GAME_ITEM_COUNT_TITLE_%@", nil), _capitalizedPluralItemDescription];
scoreView.title = ORKLocalizedString(@"MEMORY_GAME_SCORE_TITLE", nil);
countView.enabled = YES;
scoreView.enabled = YES;
@@ -229,18 +229,25 @@
- (void)setCapitalizedPluralItemDescription:(NSString *)capitalizedPluralItemDescription {
_capitalizedPluralItemDescription = capitalizedPluralItemDescription;
[self countView].title = [NSString stringWithFormat:ORKLocalizedString(@"MEMORY_GAME_ITEM_COUNT_TITLE_%@", nil), _capitalizedPluralItemDescription];
[self countView].title = [NSString localizedStringWithFormat:ORKLocalizedString(@"MEMORY_GAME_ITEM_COUNT_TITLE_%@", nil), _capitalizedPluralItemDescription];
}
- (void)setNumberOfItems:(NSInteger)numberOfItems {
ORKActiveStepQuantityView *countView = [self countView];
countView.value = [NSString stringWithFormat:@"%ld", (long)numberOfItems];
countView.value = [self stringWithNumberFormatter:numberOfItems];
}
- (void)setScore:(NSInteger)score {
ORKActiveStepQuantityView *scoreView = [self scoreView];
scoreView.value = [NSString stringWithFormat:@"%ld", (long)score];
scoreView.value = [self stringWithNumberFormatter:score];
}
- (NSString *)stringWithNumberFormatter: (NSInteger)integer {
NSNumberFormatter *formatter = [NSNumberFormatter new];
formatter.numberStyle = NSNumberFormatterNoStyle;
formatter.locale = [NSLocale currentLocale];
return [NSString stringWithFormat:@"%@", [formatter stringFromNumber:[NSNumber numberWithLong:(long)integer]]];
}
- (void)updateFooterHidden {
@@ -37,6 +37,7 @@
#import "ORKActiveStepViewController_Internal.h"
#import "ORKStepViewController_Internal.h"
#import "ORKStepHeaderView_Internal.h"
#import "ORKActiveStep_Internal.h"
#import "ORKResult.h"
@@ -116,6 +117,8 @@ typedef void (^_ORKStateHandler)(ORKState *fromState, ORKState *_toState, id con
ORKGridSize _gridSize;
ORKSpatialSpanGameState *_currentGameState;
UIBarButtonItem *_customLearnMoreButtonItem;
UIBarButtonItem *_learnMoreButtonItem;
// ORKSpatialSpanMemoryGameRecord
NSMutableArray *_gameRecords;
@@ -150,6 +153,13 @@ typedef void (^_ORKStateHandler)(ORKState *fromState, ORKState *_toState, id con
#pragma mark Overrides
- (void)viewDidLoad {
// Setup to always have a learn more button item but with an empty title
BOOL usesDefaultCopyright = (self.learnMoreButtonItem == nil);
if (usesDefaultCopyright) {
self.learnMoreButtonItem = [[UIBarButtonItem alloc] initWithTitle:ORKLocalizedString(@"BUTTON_COPYRIGHT", nil) style:UIBarButtonItemStylePlain target:self action:@selector(showCopyright)];
}
[super viewDidLoad];
_contentView = [ORKSpatialSpanMemoryContentView new];
@@ -164,6 +174,10 @@ typedef void (^_ORKStateHandler)(ORKState *fromState, ORKState *_toState, id con
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleUserTap:)];
[self.activeStepView addGestureRecognizer:tapGestureRecognizer];
if (usesDefaultCopyright) {
self.activeStepView.headerView.learnMoreButton.alpha = 0;
}
}
- (void)stepDidChange {
@@ -440,7 +454,7 @@ typedef void (^_ORKStateHandler)(ORKState *fromState, ORKState *_toState, id con
_contentView.footerHidden = YES;
_contentView.buttonItem = nil;
ORKSpatialSpanMemoryStep *step = [self spatialSpanStep];
NSString *title = [NSString stringWithFormat:ORKLocalizedString(@"MEMORY_GAME_PLAYBACK_TITLE_%@", nil), step.customTargetPluralName ? : ORKLocalizedString(@"SPATIAL_SPAN_MEMORY_TARGET_PLURAL", nil)];
NSString *title = [NSString localizedStringWithFormat:ORKLocalizedString(@"MEMORY_GAME_PLAYBACK_TITLE_%@", nil), step.customTargetPluralName ? : ORKLocalizedString(@"SPATIAL_SPAN_MEMORY_TARGET_PLURAL", nil)];
[self.activeStepView updateTitle:title text:nil];
@@ -634,11 +648,24 @@ typedef void (^_ORKStateHandler)(ORKState *fromState, ORKState *_toState, id con
- (void)showComplete {
[self.activeStepView updateTitle:ORKLocalizedString(@"MEMORY_GAME_COMPLETE_TITLE", nil) text:nil];
// Show the copyright
self.activeStepView.headerView.learnMoreButton.alpha = 1;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.75 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_contentView.buttonItem = [[UIBarButtonItem alloc] initWithTitle:ORKLocalizedString(@"BUTTON_NEXT", nil) style:UIBarButtonItemStylePlain target:self action:@selector(continueAction)];
});
}
- (void)showCopyright {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
message:ORKLocalizedString(@"MEMORY_GAME_COPYRIGHT_TEXT", nil)
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:ORKLocalizedString(@"BUTTON_OK", nil)
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
}
#pragma mark ORKSpatialSpanStepStateRestart
- (void)doRestart {
@@ -0,0 +1,50 @@
/*
Copyright (c) 2017, Apple Inc. 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 UIKit;
#import "ORKCustomStepView_Internal.h"
NS_ASSUME_NONNULL_BEGIN
@class ORKBorderedButton;
@interface ORKStroopContentView : ORKActiveStepCustomView
@property (nonatomic) NSString * colorLabelText;
@property (nonatomic) UIColor * colorLabelColor;
@property (nonatomic) ORKBorderedButton * RButton;
@property (nonatomic) ORKBorderedButton * GButton;
@property (nonatomic) ORKBorderedButton * BButton;
@property (nonatomic) ORKBorderedButton * YButton;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,242 @@
/*
Copyright (c) 2017, Apple Inc. 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 "ORKStroopContentView.h"
#import "ORKUnitLabel.h"
#import "ORKHelpers_Internal.h"
#import "ORKSkin.h"
#import "ORKBorderedButton.h"
@implementation ORKStroopContentView {
UILabel *_colorLabel;
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.translatesAutoresizingMaskIntoConstraints = NO;
_colorLabel = [UILabel new];
_colorLabel.numberOfLines = 1;
_colorLabel.textAlignment = NSTextAlignmentCenter;
_colorLabel.translatesAutoresizingMaskIntoConstraints = NO;
[_colorLabel setFont:[UIFont systemFontOfSize:60]];
[_colorLabel setAdjustsFontSizeToFitWidth:YES];
self.RButton = [[ORKBorderedButton alloc] init];
self.RButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.RButton setTitle:ORKLocalizedString(@"STROOP_COLOR_RED_INITIAL", nil) forState:UIControlStateNormal];
self.GButton = [[ORKBorderedButton alloc] init];
self.GButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.GButton setTitle:ORKLocalizedString(@"STROOP_COLOR_GREEN_INITIAL", nil) forState:UIControlStateNormal];
self.BButton = [[ORKBorderedButton alloc] init];
self.BButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.BButton setTitle:ORKLocalizedString(@"STROOP_COLOR_BLUE_INITIAL", nil) forState:UIControlStateNormal];
self.YButton = [[ORKBorderedButton alloc] init];
self.YButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.YButton setTitle:ORKLocalizedString(@"STROOP_COLOR_YELLOW_INITIAL", nil) forState:UIControlStateNormal];
[self addSubview:_colorLabel];
[self addSubview:self.RButton];
[self addSubview:self.GButton];
[self addSubview:self.BButton];
[self addSubview:self.YButton];
[self setUpConstraints];
}
return self;
}
- (void)setColorLabelText:(NSString *)colorLabelText {
[_colorLabel setText:colorLabelText];
[self setNeedsDisplay];
}
- (void)setColorLabelColor:(UIColor *)colorLabelColor {
[_colorLabel setTextColor:colorLabelColor];
[self setNeedsDisplay];
}
- (NSString *)colorLabelText {
return _colorLabel.text;
}
- (UIColor *)colorLabelColor {
return _colorLabel.textColor;
}
- (void)setUpConstraints {
NSMutableArray *constraints = [NSMutableArray array];
NSDictionary *views = NSDictionaryOfVariableBindings(_colorLabel, _RButton, _GButton, _BButton, _YButton);
CGFloat minimumButtonHeight = 60;
[constraints addObjectsFromArray:@[
[NSLayoutConstraint constraintWithItem:_colorLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:self.RButton
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:minimumButtonHeight],
[NSLayoutConstraint constraintWithItem:self.RButton
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:minimumButtonHeight],
[NSLayoutConstraint constraintWithItem:self.GButton
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:minimumButtonHeight],
[NSLayoutConstraint constraintWithItem:self.GButton
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:minimumButtonHeight],
[NSLayoutConstraint constraintWithItem:self.BButton
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:minimumButtonHeight],
[NSLayoutConstraint constraintWithItem:self.BButton
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:minimumButtonHeight],
[NSLayoutConstraint constraintWithItem:self.YButton
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:minimumButtonHeight],
[NSLayoutConstraint constraintWithItem:self.YButton
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:minimumButtonHeight]
]];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_colorLabel]-(==300)-|"
options:NSLayoutFormatAlignAllCenterX
metrics:nil
views:views]];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(>=10)-[_colorLabel]-(>=10)-|"
options:NSLayoutFormatAlignAllCenterX
metrics:nil
views:views]];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_RButton]-(==100)-|"
options:NSLayoutFormatAlignAllCenterX
metrics:nil
views:views]];
[constraints addObjectsFromArray:@[
[NSLayoutConstraint constraintWithItem:self.GButton
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:-10.0],
[NSLayoutConstraint constraintWithItem:self.BButton
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:10.0],
[NSLayoutConstraint constraintWithItem:self.RButton
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:self.GButton
attribute:NSLayoutAttributeLeading
multiplier:1.0
constant:-20.0],
[NSLayoutConstraint constraintWithItem:self.YButton
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self.BButton
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:20.0],
[NSLayoutConstraint constraintWithItem:self.GButton
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.RButton
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:self.BButton
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.RButton
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:self.YButton
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.RButton
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]]];
[self addConstraints:constraints];
[NSLayoutConstraint activateConstraints:constraints];
}
@end
+44
View File
@@ -0,0 +1,44 @@
/*
Copyright (c) 2017, Apple Inc. 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 <ResearchKit/ORKDefines.h>
#import <ResearchKit/ORKActiveStep.h>
NS_ASSUME_NONNULL_BEGIN
ORK_CLASS_AVAILABLE
@interface ORKStroopStep : ORKActiveStep
@property (nonatomic, assign) NSInteger numberOfAttempts;
@end
NS_ASSUME_NONNULL_END
+100
View File
@@ -0,0 +1,100 @@
/*
Copyright (c) 2017, Apple Inc. 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 "ORKStroopStep.h"
#import "ORKStroopStepViewController.h"
#import "ORKHelpers_Internal.h"
@implementation ORKStroopStep
+ (Class)stepViewControllerClass {
return [ORKStroopStepViewController class];
}
+ (BOOL)supportsSecureCoding {
return YES;
}
- (instancetype)initWithIdentifier:(NSString *)identifier {
self = [super initWithIdentifier:identifier];
if (self) {
self.shouldVibrateOnStart = YES;
self.shouldShowDefaultTimer = NO;
self.shouldContinueOnFinish = YES;
self.stepDuration = NSIntegerMax;
}
return self;
}
- (void)validateParameters {
[super validateParameters];
NSInteger minimumAttempts = 10;
if (self.numberOfAttempts < minimumAttempts) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"number of attempts should be greater or equal to %ld.", (long)minimumAttempts] userInfo:nil];
}
}
- (BOOL)startsFinished {
return NO;
}
- (BOOL)allowsBackNavigation {
return NO;
}
- (instancetype)copyWithZone:(NSZone *)zone {
ORKStroopStep *step = [super copyWithZone:zone];
step.numberOfAttempts = self.numberOfAttempts;
return step;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self ) {
ORK_DECODE_INTEGER(aDecoder, numberOfAttempts);
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[super encodeWithCoder:aCoder];
ORK_ENCODE_INTEGER(aCoder, numberOfAttempts);
}
- (BOOL)isEqual:(id)object {
BOOL isParentSame = [super isEqual:object];
__typeof(self) castObject = object;
return (isParentSame && (self.numberOfAttempts == castObject.numberOfAttempts));
}
@end
@@ -0,0 +1,44 @@
/*
Copyright (c) 2017, Apple Inc. 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;
#import <ResearchKit/ORKDefines.h>
#import <ResearchKit/ORKActiveStepViewController.h>
NS_ASSUME_NONNULL_BEGIN
ORK_CLASS_AVAILABLE
@interface ORKStroopStepViewController : ORKActiveStepViewController
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,243 @@
/*
Copyright (c) 2017, Apple Inc. 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 "ORKStroopStepViewController.h"
#import "ORKActiveStepView.h"
#import "ORKStroopContentView.h"
#import "ORKActiveStepViewController_Internal.h"
#import "ORKStepViewController_Internal.h"
#import "ORKResult.h"
#import "ORKStroopStep.h"
#import "ORKHelpers_Internal.h"
#import "ORKBorderedButton.h"
@interface ORKStroopStepViewController ()
@property (nonatomic, strong) ORKStroopContentView *stroopContentView;
@property (nonatomic, copy) NSMutableDictionary *colors;
@property (nonatomic, copy) NSMutableDictionary *differentColorLabels;
@property (nonatomic) NSUInteger questionNumber;
@end
@implementation ORKStroopStepViewController {
UIColor *_red;
UIColor *_green;
UIColor *_blue;
UIColor *_yellow;
NSString *_redString;
NSString *_greenString;
NSString *_blueString;
NSString *_yellowString;
NSTimer *_nextQuestionTimer;
NSMutableArray *_results;
NSTimeInterval _startTime;
NSTimeInterval _endTime;
}
- (instancetype)initWithStep:(ORKStep *)step {
self = [super initWithStep:step];
if (self) {
self.suspendIfInactive = YES;
}
return self;
}
- (ORKStroopStep *)stroopStep {
return (ORKStroopStep *)self.step;
}
- (void)viewDidLoad {
[super viewDidLoad];
_results = [NSMutableArray new];
_redString = ORKLocalizedString(@"STROOP_COLOR_RED", nil);
_greenString = ORKLocalizedString(@"STROOP_COLOR_GREEN", nil);
_blueString = ORKLocalizedString(@"STROOP_COLOR_BLUE", nil);
_yellowString = ORKLocalizedString(@"STROOP_COLOR_YELLOW", nil);
_red = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0];
_green = [UIColor colorWithRed:0.0 green:1.0 blue:0.0 alpha:1.0];
_blue = [UIColor colorWithRed:0.0 green:0.0 blue:1.0 alpha:1.0];
_yellow = [UIColor colorWithRed:1.0 green:1.0 blue:0.0 alpha:1.0];
self.colors = [[NSMutableDictionary alloc] initWithObjectsAndKeys: _red, _redString, _blue, _blueString, _yellow, _yellowString, _green, _greenString, nil];
self.differentColorLabels = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSArray arrayWithObjects:_blue,
_green,
_yellow, nil], _redString,
[NSArray arrayWithObjects:_red,
_green,
_yellow, nil], _blueString,
[NSArray arrayWithObjects:_red,
_blue,
_green, nil], _yellowString,
[NSArray arrayWithObjects:_red,
_blue,
_yellow, nil], _greenString, nil];
self.questionNumber = 0;
_stroopContentView = [ORKStroopContentView new];
self.activeStepView.activeCustomView = _stroopContentView;
self.activeStepView.stepViewFillsAvailableSpace = YES;
[self.stroopContentView.RButton addTarget:self
action:@selector(buttonPressed:)
forControlEvents:UIControlEventTouchUpInside];
[self.stroopContentView.GButton addTarget:self
action:@selector(buttonPressed:)
forControlEvents:UIControlEventTouchUpInside];
[self.stroopContentView.BButton addTarget:self
action:@selector(buttonPressed:)
forControlEvents:UIControlEventTouchUpInside];
[self.stroopContentView.YButton addTarget:self
action:@selector(buttonPressed:)
forControlEvents:UIControlEventTouchUpInside];
}
- (void)buttonPressed:(id)sender {
if (![self.stroopContentView.colorLabelText isEqualToString:@" "]) {
[self setButtonsDisabled];
if (sender == self.stroopContentView.RButton) {
[self createResult:[self.colors allKeysForObject:self.stroopContentView.colorLabelColor][0] withText:self.stroopContentView.colorLabelText withColorSelected:_redString];
}
else if (sender == self.stroopContentView.GButton) {
[self createResult:[self.colors allKeysForObject:self.stroopContentView.colorLabelColor][0] withText:self.stroopContentView.colorLabelText withColorSelected:_greenString];
}
else if (sender == self.stroopContentView.BButton) {
[self createResult:[self.colors allKeysForObject:self.stroopContentView.colorLabelColor][0] withText:self.stroopContentView.colorLabelText withColorSelected:_blueString];
}
else if (sender == self.stroopContentView.YButton) {
[self createResult:[self.colors allKeysForObject:self.stroopContentView.colorLabelColor][0] withText:self.stroopContentView.colorLabelText withColorSelected:_yellowString];
}
self.stroopContentView.colorLabelText = @" ";
_nextQuestionTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:@selector(startNextQuestionOrFinish)
userInfo:nil
repeats:NO];
}
}
- (void)startNextQuestionTimer {
_nextQuestionTimer = [NSTimer scheduledTimerWithTimeInterval:0.3
target:self
selector:@selector(startNextQuestionOrFinish)
userInfo:nil
repeats:NO];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self start];
}
- (void)stepDidFinish {
[super stepDidFinish];
[self.stroopContentView finishStep:self];
[self goForward];
}
- (ORKStepResult *)result {
ORKStepResult *stepResult = [super result];
if (_results) {
stepResult.results = [_results copy];
}
return stepResult;
}
- (void)start {
[super start];
[self startQuestion];
}
#pragma mark - ORKResult
- (void)createResult:(NSString *)color withText:(NSString *)text withColorSelected:(NSString *)colorSelected {
ORKStroopResult *stroopResult = [[ORKStroopResult alloc] initWithIdentifier:self.step.identifier];
stroopResult.startTime = _startTime;
stroopResult.endTime = [NSProcessInfo processInfo].systemUptime;
stroopResult.color = color;
stroopResult.text = text;
stroopResult.colorSelected = colorSelected;
[_results addObject:stroopResult];
}
- (void)startNextQuestionOrFinish {
self.questionNumber = self.questionNumber + 1;
if (self.questionNumber == ([self stroopStep].numberOfAttempts)) {
[self finish];
} else {
[self startQuestion];
}
}
- (void)startQuestion {
int pattern = arc4random() % 2;
if (pattern == 0) {
int index = arc4random() % [self.colors.allKeys count];
NSString *text = [self.colors.allKeys objectAtIndex:index];
self.stroopContentView.colorLabelText = text;
UIColor *color = [self.colors valueForKey:text];
self.stroopContentView.colorLabelColor = color;
}
else {
int index = arc4random() % [self.differentColorLabels.allKeys count];
NSString *text = [self.differentColorLabels.allKeys objectAtIndex:index];
self.stroopContentView.colorLabelText = text;
NSArray *colorArray = [self.differentColorLabels valueForKey:text];
int randomColor = arc4random() % colorArray.count;
UIColor *color = [colorArray objectAtIndex:randomColor];
self.stroopContentView.colorLabelColor = color;
}
[self setButtonsEnabled];
_startTime = [NSProcessInfo processInfo].systemUptime;
}
- (void)setButtonsDisabled {
[self.stroopContentView.RButton setEnabled: NO];
[self.stroopContentView.GButton setEnabled: NO];
[self.stroopContentView.BButton setEnabled: NO];
[self.stroopContentView.YButton setEnabled: NO];
}
- (void)setButtonsEnabled {
[self.stroopContentView.RButton setEnabled: YES];
[self.stroopContentView.GButton setEnabled: YES];
[self.stroopContentView.BButton setEnabled: YES];
[self.stroopContentView.YButton setEnabled: YES];
}
@end
@@ -98,10 +98,13 @@
NSDictionary *views = NSDictionaryOfVariableBindings(_progressView, _imageView);
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_progressView]|"
options:(NSLayoutFormatOptions)0
metrics:nil views:views]];
[constraints addObject:[NSLayoutConstraint constraintWithItem:_progressView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_progressView]-(>=10)-[_imageView]-|"
@@ -74,7 +74,7 @@
[super initializeInternalButtonItems];
self.internalDoneButtonItem = nil;
self.continueButtonTitle = ORKLocalizedString(@"BUTTON_DONE", nil);
self.continueButtonTitle = ORKLocalizedString(@"BUTTON_NEXT", nil);
}
- (void)viewDidLoad {
@@ -43,7 +43,8 @@ NS_ASSUME_NONNULL_BEGIN
caption:(NSString *)caption
animated:(BOOL)animated;
@property (nonatomic, strong, readonly) ORKRoundTappingButton *tapButton;
@property (nonatomic, strong, readonly) ORKRoundTappingButton *leftButton;
@property (nonatomic, strong, readonly) ORKRoundTappingButton *rightButton;
@end
@@ -49,38 +49,61 @@
@implementation ORKToneAudiometryContentView {
NSLayoutConstraint *_topToProgressViewConstraint;
NSLayoutConstraint *_topToCaptionLabelConstraint;
NSLayoutConstraint *_tapButtonToBottomConstraint;
NSLayoutConstraint *_leftButtonToBottomConstraint;
NSLayoutConstraint *_rightButtonToBottomConstraint;
UILabel *_leftLabel;
UILabel *_rightLabel;
}
- (instancetype)init {
self = [super init];
if (self) {
_captionLabel = [ORKUnitLabel new];
_captionLabel.textAlignment = NSTextAlignmentCenter;
_captionLabel.translatesAutoresizingMaskIntoConstraints = NO;
_progressView = [UIProgressView new];
_progressView.translatesAutoresizingMaskIntoConstraints = NO;
_progressView.progressTintColor = [self tintColor];
[_progressView setAlpha:0];
_tapButton = [[ORKRoundTappingButton alloc] init];
_tapButton.translatesAutoresizingMaskIntoConstraints = NO;
[_tapButton setTitle:ORKLocalizedString(@"TAP_BUTTON_TITLE", nil) forState:UIControlStateNormal];
_leftButton = [[ORKRoundTappingButton alloc] init];
_leftButton.translatesAutoresizingMaskIntoConstraints = NO;
[_leftButton setTitle:ORKLocalizedString(@"TAP_BUTTON_TITLE", nil) forState:UIControlStateNormal];
_rightButton = [[ORKRoundTappingButton alloc] init];
_rightButton.translatesAutoresizingMaskIntoConstraints = NO;
[_rightButton setTitle:ORKLocalizedString(@"TAP_BUTTON_TITLE", nil) forState: UIControlStateNormal];
_leftLabel = [ORKUnitLabel new];
_rightLabel = [ORKUnitLabel new];
_leftLabel.text = ORKLocalizedString(@"TONE_AUDIOMETRY_LABEL_LEFT_EAR", nil);
_rightLabel.text = ORKLocalizedString(@"TONE_AUDIOMETRY_LABEL_RIGHT_EAR", nil);
_leftLabel.textColor = [UIColor lightGrayColor];
_rightLabel.textColor = [UIColor lightGrayColor];
_leftLabel.translatesAutoresizingMaskIntoConstraints = NO;
_rightLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_captionLabel];
[self addSubview:_progressView];
[self addSubview:_tapButton];
[self addSubview:_leftButton];
[self addSubview:_rightButton];
[self addSubview:_leftLabel];
[self addSubview:_rightLabel];
self.translatesAutoresizingMaskIntoConstraints = NO;
_captionLabel.text = nil;
[_captionLabel setHidden:YES];
[self setUpConstraints];
[self updateConstraintConstantsForWindow:self.window];
}
return self;
}
@@ -98,7 +121,7 @@
caption:(NSString *)caption
animated:(BOOL)animated {
self.captionLabel.text = caption;
[self.progressView setProgress:progress animated:animated];
[UIView animateWithDuration:animated ? 0.2 : 0 animations:^{
[self.progressView setAlpha:(progress == 0) ? 0 : 1];
@@ -107,17 +130,20 @@
- (void)finishStep:(ORKActiveStepViewController *)viewController {
[super finishStep:viewController];
self.tapButton.enabled = NO;
self.leftButton.enabled = NO;
self.rightButton.enabled = NO;
}
- (void)updateConstraintConstantsForWindow:(UIWindow *)window {
const CGFloat HeaderBaselineToCaptionTop = ORKGetMetricForWindow(ORKScreenMetricCaptionBaselineToTappingLabelTop, window);
const CGFloat AssumedHeaderBaselineToStepViewTop = ORKGetMetricForWindow(ORKScreenMetricLearnMoreBaselineToStepViewTop, window);
static const CGFloat TapButtonBottomToBottom = 36.0;
static const CGFloat buttonBottomToBottom = 36.0;
_topToProgressViewConstraint.constant = (HeaderBaselineToCaptionTop / 3) - AssumedHeaderBaselineToStepViewTop;
_topToCaptionLabelConstraint.constant = HeaderBaselineToCaptionTop - AssumedHeaderBaselineToStepViewTop;
_tapButtonToBottomConstraint.constant = TapButtonBottomToBottom;
_leftButtonToBottomConstraint.constant = buttonBottomToBottom;
_rightButtonToBottomConstraint.constant = buttonBottomToBottom;
}
- (void)updateLayoutMargins {
@@ -129,7 +155,7 @@
[super setFrame:frame];
[self updateLayoutMargins];
}
- (void)setBounds:(CGRect)bounds {
[super setBounds:bounds];
[self updateLayoutMargins];
@@ -137,8 +163,10 @@
- (void)setUpConstraints {
NSMutableArray *constraints = [NSMutableArray array];
NSDictionary *views = NSDictionaryOfVariableBindings(_progressView, _captionLabel, _tapButton);
NSDictionary *views = NSDictionaryOfVariableBindings(_progressView, _captionLabel, _leftButton, _rightButton, _leftLabel, _rightLabel);
_topToProgressViewConstraint = [NSLayoutConstraint constraintWithItem:_progressView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
@@ -147,7 +175,7 @@
multiplier:1.0
constant:0.0]; // constant will be set in updateConstraintConstantsForWindow:
[constraints addObject:_topToProgressViewConstraint];
_topToCaptionLabelConstraint = [NSLayoutConstraint constraintWithItem:_captionLabel
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
@@ -156,22 +184,83 @@
multiplier:1.0
constant:0.0]; // constant will be set in updateConstraintConstantsForWindow:
[constraints addObject:_topToCaptionLabelConstraint];
_tapButtonToBottomConstraint = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:_tapButton
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0.0]; // constant will be set in updateConstraintConstantsForWindow:
[constraints addObject:_tapButtonToBottomConstraint];
_leftButtonToBottomConstraint = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:_leftButton
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0.0]; // constant will be set in updateConstraintConstantsForWindow:
[constraints addObject:_leftButtonToBottomConstraint];
_rightButtonToBottomConstraint = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:_rightButton
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0.0];
[constraints addObject:_rightButtonToBottomConstraint];
[constraints addObject:[NSLayoutConstraint constraintWithItem:_captionLabel
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:_leftButton
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:0.0]];
[constraints addObject:[NSLayoutConstraint constraintWithItem:_captionLabel
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:_rightButton
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:0.0]];
[constraints addObject:[NSLayoutConstraint constraintWithItem:_leftLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:_leftButton
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[constraints addObject:[NSLayoutConstraint constraintWithItem:_rightLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:_rightButton
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_captionLabel]-(>=10)-[_tapButton]"
options:NSLayoutFormatAlignAllCenterX
[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_captionLabel]-(>=10)-[_leftButton]"
options:(NSLayoutFormatOptions)0
metrics:nil
views:views]];
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_captionLabel]-(>=10)-[_rightButton]"
options:(NSLayoutFormatOptions)0
metrics:nil
views:views]];
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_leftButton]-(>=10)-[_leftLabel]"
options:(NSLayoutFormatOptions)0
metrics:nil
views:views]];
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_rightButton]-(>=10)-[_rightLabel]"
options:(NSLayoutFormatOptions)0
metrics:nil
views:views]];
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_progressView]-|"
options:(NSLayoutFormatOptions)0
@@ -192,17 +281,9 @@
options:(NSLayoutFormatOptions)0
metrics:nil
views:views]];
[constraints addObject:[NSLayoutConstraint constraintWithItem:_tapButton
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[self addConstraints:constraints];
[NSLayoutConstraint activateConstraints:constraints];
}
@@ -30,7 +30,6 @@
#import "ORKToneAudiometryPracticeStep.h"
#import "ORKToneAudiometryPracticeStepViewController.h"
@@ -35,6 +35,7 @@
NS_ASSUME_NONNULL_BEGIN
ORK_CLASS_AVAILABLE
@interface ORKToneAudiometryPracticeStepViewController : ORKActiveStepViewController
@end
@@ -82,12 +82,16 @@
self.toneAudiometryContentView = [[ORKToneAudiometryContentView alloc] init];
self.activeStepView.activeCustomView = self.toneAudiometryContentView;
[self.toneAudiometryContentView.tapButton addTarget:self action:@selector(buttonPressed:forEvent:) forControlEvents:UIControlEventTouchDown];
[self.toneAudiometryContentView.leftButton addTarget:self
action:@selector(buttonPressed:forEvent:)
forControlEvents:UIControlEventTouchDown];
[self.toneAudiometryContentView.rightButton addTarget:self
action:@selector(buttonPressed:forEvent:)
forControlEvents:UIControlEventTouchDown];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self start];
}
@@ -44,6 +44,8 @@
#import "ORKHelpers_Internal.h"
#import <MediaPlayer/MediaPlayer.h>
@interface ORKToneAudiometryStepViewController ()
@@ -51,13 +53,13 @@
@property (nonatomic, strong) ORKAudioGenerator *audioGenerator;
@property (nonatomic, assign) BOOL expired;
@property (nonatomic, copy) NSArray *testingFrequencies;
@property (nonatomic) NSArray *listOfFrequencies;
@property (nonatomic) NSMutableArray *frequencies;
@property (nonatomic, assign) NSUInteger currentTestIndex;
@property (nonatomic, strong) NSMutableArray *samples;
- (IBAction)buttonPressed:(id)button forEvent:(UIEvent *)event;
@property (nonatomic) ORKAudioChannel currentTestChannel;
- (ORKToneAudiometryStep *)toneAudiometryStep;
@end
@@ -67,17 +69,17 @@
- (instancetype)initWithStep:(ORKStep *)step {
self = [super initWithStep:step];
if (self) {
self.suspendIfInactive = YES;
}
return self;
}
- (void)initializeInternalButtonItems {
[super initializeInternalButtonItems];
// Don't show next button
self.internalContinueButtonItem = nil;
self.internalDoneButtonItem = nil;
@@ -85,55 +87,69 @@
- (void)viewDidLoad {
[super viewDidLoad];
self.expired = NO;
self.listOfFrequencies = @[ @8000, @4000, @1000, @500, @250 ];
[self generateFrequencyCombination];
self.toneAudiometryContentView = [[ORKToneAudiometryContentView alloc] init];
self.activeStepView.activeCustomView = self.toneAudiometryContentView;
[self.toneAudiometryContentView.tapButton addTarget:self action:@selector(buttonPressed:forEvent:) forControlEvents:UIControlEventTouchDown];
[self.toneAudiometryContentView.leftButton addTarget:self action:@selector(buttonPressed:forEvent:) forControlEvents:UIControlEventTouchDown];
[self.toneAudiometryContentView.rightButton addTarget:self action:@selector(buttonPressed:forEvent:) forControlEvents:UIControlEventTouchDown];
self.currentTestIndex = 0;
self.testingFrequencies = @[@250, @500, @1000, @2000, @4000, @8000];
self.audioGenerator = [ORKAudioGenerator new];
}
- (void)generateFrequencyCombination {
int numberOfChannels = 2;
self.frequencies = [[NSMutableArray alloc] init];
for (int i = 0; i<[self.listOfFrequencies count]; i++) {
for (int j = 0; j < numberOfChannels; j++) {
[self.frequencies addObject:@[self.listOfFrequencies[i], [NSNumber numberWithInt:j]]];
}
}
for (int k = 0; k<[self.frequencies count]; k++) {
[self.frequencies exchangeObjectAtIndex:(arc4random() % [self.frequencies count]) withObjectAtIndex:(arc4random() % [self.frequencies count])];
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self start];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.audioGenerator stop];
}
- (ORKStepResult *)result {
ORKStepResult *sResult = [super result];
// "Now" is the end time of the result, which is either actually now,
// or the last time we were in the responder chain.
NSDate *now = sResult.endDate;
NSMutableArray *results = [NSMutableArray arrayWithArray:sResult.results];
ORKToneAudiometryResult *toneResult = [[ORKToneAudiometryResult alloc] initWithIdentifier:self.step.identifier];
toneResult.startDate = sResult.startDate;
toneResult.endDate = now;
toneResult.samples = [self.samples copy];
toneResult.outputVolume = @([AVAudioSession sharedInstance].outputVolume);
[results addObject:toneResult];
sResult.results = [results copy];
return sResult;
}
- (void)stepDidFinish {
[super stepDidFinish];
self.expired = YES;
[self.toneAudiometryContentView finishStep:self];
[self goForward];
@@ -141,53 +157,52 @@
- (void)start {
[super start];
[self startCurrentTest];
}
- (void)suspend {
[super suspend];
// ...
}
- (void)resume {
[super resume];
// ...
}
- (void)finish {
[super finish];
// ...
}
- (IBAction)buttonPressed:(id)button forEvent:(UIEvent *)event {
if (self.samples == nil) {
_samples = [NSMutableArray array];
}
ORKToneAudiometrySample *sample = [ORKToneAudiometrySample new];
NSUInteger frequencyIndex = (self.currentTestIndex / 2);
NSNumber *frequency = self.testingFrequencies[frequencyIndex];
NSUInteger frequencyIndex = self.currentTestIndex;
NSNumber *frequency = self.frequencies[frequencyIndex][0];
sample.frequency = [frequency doubleValue];
sample.channel = ((self.currentTestIndex % 2) == 0) ? ORKAudioChannelLeft : ORKAudioChannelRight;
sample.channel = self.currentTestChannel;
sample.channelSelected = (button == self.toneAudiometryContentView.leftButton) ? ORKAudioChannelLeft : ORKAudioChannelRight;
sample.amplitude = self.audioGenerator.volumeAmplitude;
[self.samples addObject:sample];
[self.audioGenerator stop];
[self startNextTestOrFinish];
}
- (void)testExpired {
if (self.samples == nil) {
_samples = [NSMutableArray array];
}
ORKToneAudiometrySample *sample = [ORKToneAudiometrySample new];
NSUInteger frequencyIndex = self.currentTestIndex;
NSNumber *frequency = self.frequencies[frequencyIndex][0];
sample.frequency = [frequency doubleValue];
sample.channel = self.currentTestChannel;
sample.channelSelected = -1;
sample.amplitude = self.audioGenerator.volumeAmplitude;
[self.samples addObject:sample];
[self.audioGenerator stop];
[self startNextTestOrFinish];
}
- (void)startNextTestOrFinish {
self.currentTestIndex ++;
if (self.currentTestIndex == (self.testingFrequencies.count * 2)) {
if (self.currentTestIndex == (self.frequencies.count)) {
[self finish];
} else {
[self startCurrentTest];
@@ -200,31 +215,35 @@
- (void)startCurrentTest {
const NSTimeInterval SoundDuration = self.toneAudiometryStep.toneDuration;
NSUInteger testIndex = self.currentTestIndex;
NSUInteger frequencyIndex = (testIndex / 2);
NSAssert(frequencyIndex < self.testingFrequencies.count, nil);
NSNumber *frequency = self.testingFrequencies[frequencyIndex];
ORKAudioChannel channel = ((testIndex % 2) == 0) ? ORKAudioChannelLeft : ORKAudioChannelRight;
CGFloat progress = 0.001 + (CGFloat)testIndex / (self.testingFrequencies.count * 2);
NSUInteger frequencyIndex = testIndex;
NSAssert(frequencyIndex < self.frequencies.count, nil);
NSNumber *frequency = self.frequencies[frequencyIndex][0];
self.currentTestChannel = ([self.frequencies[frequencyIndex][1] intValue] == 0) ? ORKAudioChannelLeft : ORKAudioChannelRight;
ORKAudioChannel channel = self.currentTestChannel;
CGFloat progress = 0.001 + (CGFloat)testIndex / self.frequencies.count;
[self.toneAudiometryContentView setProgress:progress
caption:(channel == ORKAudioChannelLeft) ? [NSString stringWithFormat:ORKLocalizedString(@"TONE_LABEL_%@_LEFT", nil), ORKLocalizedStringFromNumber(frequency)] : [NSString stringWithFormat:ORKLocalizedString(@"TONE_LABEL_%@_RIGHT", nil), ORKLocalizedStringFromNumber(frequency)]
animated:YES];
[self.audioGenerator playSoundAtFrequency:frequency.doubleValue
onChannel:channel
fadeInDuration:SoundDuration];
ORKWeakTypeOf(self)weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(SoundDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
ORKStrongTypeOf(self) strongSelf = weakSelf;
if (strongSelf.currentTestIndex == testIndex) {
[strongSelf testExpired];
}
});
}
@end
@@ -0,0 +1,58 @@
/*
Copyright (c) 2016, Darren Levy. 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;
#import <ResearchKit/ORKDefines.h>
#import <ResearchKit/ORKActiveStep.h>
NS_ASSUME_NONNULL_BEGIN
/**
The `ORKTouchAnywhereStep` class represents a step that displays a title with custom instructions
and the text "Touch anywhere to continue." The user can touch almost anywhere on the
screen and the step will end and the task will continue. The back button is still
tappable.
*/
ORK_CLASS_AVAILABLE
@interface ORKTouchAnywhereStep : ORKActiveStep
- (instancetype)init NS_UNAVAILABLE;
/**
Init with an identifier and instruction text. Instruction text should be used to tell the user
where to place the device before touching anywhere.
*/
- (instancetype)initWithIdentifier:(NSString *)identifier instructionText:(NSString *)instructionText;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,52 @@
/*
Copyright (c) 2016, Darren Levy. 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 "ORKTouchAnywhereStep.h"
#import "ORKTouchAnywhereStepViewController.h"
#import "ORKHelpers_Internal.h"
@implementation ORKTouchAnywhereStep
+ (Class)stepViewControllerClass {
return [ORKTouchAnywhereStepViewController class];
}
- (instancetype)initWithIdentifier:(NSString *)identifier instructionText:(NSString *)instructionText {
self = [super initWithIdentifier:identifier];
if (self) {
self.text = ORKLocalizedString(@"TOUCH_ANYWHERE_LABEL", nil);
self.title = instructionText;
}
return self;
}
@end
@@ -0,0 +1,44 @@
/*
Copyright (c) 2016, Darren Levy. 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;
#import <ResearchKit/ORKDefines.h>
#import <ResearchKit/ORKActiveStepViewController.h>
NS_ASSUME_NONNULL_BEGIN
ORK_CLASS_AVAILABLE
@interface ORKTouchAnywhereStepViewController : ORKActiveStepViewController
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,131 @@
/*
Copyright (c) 2016, Darren Levy. 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 "ORKTouchAnywhereStepViewController.h"
#import "ORKActiveStepViewController_Internal.h"
#import "ORKStepViewController_Internal.h"
#import "ORKCustomStepView_Internal.h"
#import "ORKLabel.h"
#import "ORKActiveStepView.h"
#import "ORKProgressView.h"
#import "ORKSkin.h"
@interface ORKTouchAnywhereView : ORKActiveStepCustomView {
NSLayoutConstraint *_topConstraint;
}
@property (nonatomic, strong) UIView *progressView;
@end
@implementation ORKTouchAnywhereView
- (instancetype)init {
self = [super init];
if (self) {
_progressView = [ORKProgressView new];
_progressView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_progressView];
[self setUpConstraints];
[self updateConstraintConstantsForWindow:self.window];
}
return self;
}
- (void)setUpConstraints {
NSMutableArray *constraints = [NSMutableArray new];
NSDictionary *views = NSDictionaryOfVariableBindings(_progressView);
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_progressView]-(>=0)-|"
options:NSLayoutFormatAlignAllCenterX
metrics:nil
views:views]];
_topConstraint = [NSLayoutConstraint constraintWithItem:_progressView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0.0]; // constant will be set in updateConstraintConstantsForWindow:
[constraints addObject:_topConstraint];
[constraints addObject:[NSLayoutConstraint constraintWithItem:_progressView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[NSLayoutConstraint activateConstraints:constraints];
}
- (void)updateConstraintConstantsForWindow:(UIWindow *)window {
const CGFloat CaptionBaselineToProgressTop = 100;
const CGFloat CaptionBaselineToStepViewTop = ORKGetMetricForWindow(ORKScreenMetricLearnMoreBaselineToStepViewTop, window);
_topConstraint.constant = CaptionBaselineToProgressTop - CaptionBaselineToStepViewTop;
}
@end
@interface ORKTouchAnywhereStepViewController ()
@property (nonatomic, strong) ORKTouchAnywhereView *touchAnywhereView;
@property (nonatomic, strong) UITapGestureRecognizer *gestureRecognizer;
@end
@implementation ORKTouchAnywhereStepViewController
- (void)viewDidLoad {
[super viewDidLoad];
_touchAnywhereView = [[ORKTouchAnywhereView alloc] init];
_touchAnywhereView.translatesAutoresizingMaskIntoConstraints = NO;
self.activeStepView.activeCustomView = _touchAnywhereView;
self.cancelButtonItem = nil;
_gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[self.activeStepView addGestureRecognizer:_gestureRecognizer];
self.internalContinueButtonItem = nil;
}
- (void)handleTap:(UIGestureRecognizer *)sender {
[self goForward];
}
@end
@@ -36,6 +36,7 @@
#import "ORKTowerOfHanoiTowerView.h"
#import "ORKActiveStepViewController_Internal.h"
#import "ORKStepViewController_Internal.h"
#import "ORKResult.h"
#import "ORKTowerOfHanoiStep.h"
@@ -123,7 +124,7 @@ static const NSUInteger NumberOfTowers = 3;
if (_firstMoveDate != nil) {
result.startDate = _firstMoveDate;
}
stepResult.results = @[result];
stepResult.results = [self.addedResults arrayByAddingObject:result] ? : @[result];
return stepResult;
}
@@ -188,7 +189,7 @@ static const NSUInteger NumberOfTowers = 3;
NSString *moves = ORKLocalizedStringFromNumber(@(self.moves.count));
NSString *time = [self.dateComponentsFormatter stringFromTimeInterval:_secondsElapsed];
NSString *title = ORKLocalizedString(@"TOWER_OF_HANOI_TASK_ACTIVE_STEP_INTRO_TEXT",nil);
NSString *text = [NSString stringWithFormat:ORKLocalizedString(@"TOWER_OF_HANOI_TASK_ACTIVE_STEP_PROGRESS_TEXT", nil), moves, time];
NSString *text = [NSString localizedStringWithFormat:ORKLocalizedString(@"TOWER_OF_HANOI_TASK_ACTIVE_STEP_PROGRESS_TEXT", nil), moves, time];
[self.activeStepView updateTitle:title text:text];
}
@@ -36,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface ORKTowerOfHanoiTower : NSObject
@property(nonatomic, copy, readonly) NSArray *disks;
@property (nonatomic, copy, readonly) NSArray *disks;
+ (instancetype)emptyTower;
@@ -34,7 +34,7 @@
@interface ORKTowerOfHanoiTower ()
@property(nonatomic, copy, readwrite) NSArray *disks;
@property (nonatomic, copy, readwrite) NSArray *disks;
@end
@@ -0,0 +1,53 @@
/*
Copyright (c) 2016, Motus Design Group Inc. 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 UIKit;
#import "ORKCustomStepView_Internal.h"
NS_ASSUME_NONNULL_BEGIN
@class ORKRoundTappingButton;
@interface ORKTrailmakingContentView : ORKActiveStepCustomView
@property (nonatomic, copy) NSArray<ORKRoundTappingButton*> *tapButtons;
- (instancetype)initWithType:(NSString *)trailType;
- (void)setLinesToDraw:(int)numLines;
- (CGRect)testArea;
- (void)setError:(int)buttonIdex;
- (void)clearErrors;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,200 @@
/*
Copyright (c) 2016, Motus Design Group Inc. 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 "ORKTrailmakingContentView.h"
#import "ORKHeadlineLabel.h"
#import "ORKLabel.h"
#import "ORKAccessibility.h"
#import "ORKHelpers_Internal.h"
#import "ORKSkin.h"
#import "ORKRoundTappingButton.h"
@interface ORKTrailmakingTestView : UIView {
int linesToDraw;
}
@end
@implementation ORKTrailmakingTestView
- (instancetype)init {
self = [super init];
if (self) {
self.contentMode = UIViewContentModeRedraw;
[self setBackgroundColor:[UIColor clearColor]];
}
return self;
}
- (void)setLinesToDraw:(int)numLines {
linesToDraw = numLines;
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextClearRect(ctx, rect);
int curLine = 0;
UIView* lastChild = nil;
for (UIView* child in self.subviews) {
if (curLine == linesToDraw)
break;
if (lastChild == nil) {
lastChild = child;
} else {
CGRect r1 = child.frame;
CGRect r2 = lastChild.frame;
CGContextSetStrokeColorWithColor(ctx, child.tintColor.CGColor);
CGContextSetLineWidth(ctx, 5.0f);
CGContextMoveToPoint(ctx, r1.origin.x + r1.size.width / 2, r1.origin.y + r1.size.height / 2);
CGContextAddLineToPoint(ctx, r2.origin.x + r2.size.width / 2, r2.origin.y + r2.size.height / 2);
CGContextStrokePath(ctx);
lastChild = child;
curLine++;
}
}
}
@end
@interface ORKTrailmakingContentView ()
@property (nonatomic, strong) ORKTrailmakingTestView* testView;
@end
@implementation ORKTrailmakingContentView
- (instancetype)initWithType:(NSString*)trailType {
self = [super initWithFrame:CGRectZero];
if (self) {
self.layoutMargins = ORKStandardFullScreenLayoutMarginsForView(self);
self.translatesAutoresizingMaskIntoConstraints = NO;
self.testView = [[ORKTrailmakingTestView alloc] init];
_testView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_testView];
NSMutableArray* buttons = [NSMutableArray array];
for (int i = 0; i < 13; i++)
{
ORKRoundTappingButton* b = [[ORKRoundTappingButton alloc] init];
NSString* title;
if ([trailType isEqual:@"A"]) {
title = [self stringWithNumberFormatter:i + 1];
} else {
NSArray *letters = [[NSArray alloc] initWithObjects:ORKLocalizedString(@"TRAILMAKING_LETTER_A", nil),
ORKLocalizedString(@"TRAILMAKING_LETTER_B", nil),
ORKLocalizedString(@"TRAILMAKING_LETTER_C", nil),
ORKLocalizedString(@"TRAILMAKING_LETTER_D", nil),
ORKLocalizedString(@"TRAILMAKING_LETTER_E", nil),
ORKLocalizedString(@"TRAILMAKING_LETTER_F", nil), nil];
if (i % 2 == 0)
title = [self stringWithNumberFormatter:i / 2 + 1];
else
title = letters[i/2];
}
[b setTitle:title forState:UIControlStateNormal];
[buttons addObject:b];
[_testView addSubview:b];
}
_tapButtons = [buttons copy];
[self setUpConstraints];
}
return self;
}
- (NSString *)stringWithNumberFormatter: (double)value {
NSNumberFormatter *formatter = [NSNumberFormatter new];
formatter.numberStyle = NSNumberFormatterNoStyle;
formatter.locale = [NSLocale currentLocale];
return [NSString stringWithFormat:@"%@", [formatter stringFromNumber:[NSNumber numberWithDouble:value]]];
}
- (void)setUpConstraints {
NSMutableArray *constraints = [NSMutableArray array];
NSDictionary *views = NSDictionaryOfVariableBindings(_testView);
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_testView(>=100)]-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:views]];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-32-[_testView(>=100)]|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:views]];
[NSLayoutConstraint activateConstraints:constraints];
}
- (void)setLinesToDraw:(int)numLines {
_testView.linesToDraw = numLines;
}
- (CGRect)testArea {
return _testView.bounds;
}
- (void)setError:(int)buttonIdex {
ORKRoundTappingButton* button = [_tapButtons objectAtIndex:buttonIdex];
[button setTintColor:[UIColor redColor]];
}
- (void)clearErrors {
for (ORKRoundTappingButton* button in _tapButtons) {
[button setTintColor:self.tintColor];
}
}
@end
@@ -0,0 +1,49 @@
/*
Copyright (c) 2016, Motus Design Group Inc. 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;
#import <ResearchKit/ORKActiveStep.h>
#import <ResearchKit/ORKOrderedTask.h>
NS_ASSUME_NONNULL_BEGIN
ORK_CLASS_AVAILABLE
@interface ORKTrailmakingStep : ORKActiveStep
/**
The type of trail to show. Default = `ORKTrailMakingTypeIdentifierA`
*/
@property (nonatomic, copy) ORKTrailMakingTypeIdentifier trailType;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,109 @@
/*
Copyright (c) 2016, Motus Design Group Inc. 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 "ORKTrailmakingStep.h"
#import "ORKTrailmakingStepViewController.h"
#import "ORKStep_Private.h"
#import "ORKHelpers_Internal.h"
@implementation ORKTrailmakingStep
+ (Class)stepViewControllerClass {
return [ORKTrailmakingStepViewController class];
}
- (instancetype)initWithIdentifier:(NSString *)identifier {
self = [super initWithIdentifier:identifier];
if (self) {
self.shouldShowDefaultTimer = NO;
self.shouldContinueOnFinish = YES;
self.optional = NO; // default to *not* optional
_trailType = ORKTrailMakingTypeIdentifierA;
}
return self;
}
- (void)validateParameters {
[super validateParameters];
NSArray *supportedTypes = @[ORKTrailMakingTypeIdentifierA, ORKTrailMakingTypeIdentifierB];
if (self.trailType == nil || ![supportedTypes containsObject:self.trailType]) {
@throw [NSException exceptionWithName:NSInvalidArgumentException
reason:@"trailType must be A or B"
userInfo:nil];
}
}
- (BOOL)startsFinished {
return NO;
}
- (id)copyWithZone:(NSZone *)zone {
ORKTrailmakingStep *step = [super copyWithZone:zone];
step.trailType = self.trailType;
return step;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
ORK_DECODE_OBJ(aDecoder, trailType);
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[super encodeWithCoder:aCoder];
ORK_ENCODE_OBJ(aCoder, trailType);
}
+ (BOOL)supportsSecureCoding {
return YES;
}
- (NSUInteger)hash {
return [super hash] ^ self.trailType.hash;
}
- (BOOL)isEqual:(id)object {
BOOL isParentSame = [super isEqual:object];
__typeof(self) castObject = object;
return (isParentSame &&
[self.trailType isEqual:castObject.trailType]);
}
@end
@@ -0,0 +1,45 @@
/*
Copyright (c) 2016, Motus Design Group Inc. 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;
#import <ResearchKit/ORKDefines.h>
#import <ResearchKit/ORKActiveStepViewController.h>
NS_ASSUME_NONNULL_BEGIN
ORK_CLASS_AVAILABLE
@interface ORKTrailmakingStepViewController : ORKActiveStepViewController {
}
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,275 @@
/*
Copyright (c) 2016, Motus Design Group Inc. 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 "ORKTrailmakingStepViewController.h"
#import "ORKActiveStepTimer.h"
#import "ORKActiveStepView.h"
#import "ORKTrailmakingContentView.h"
#import "ORKCustomStepView_Internal.h"
#import "ORKRoundTappingButton.h"
#import "ORKActiveStepViewController_Internal.h"
#import "ORKTrailmakingStep.h"
#import "ORKStep_Private.h"
#import "ORKResult.h"
#import "ORKHelpers_Internal.h"
#import "ORKStepViewController_Internal.h"
#define BOUND(lo, hi, v) (((v) < (lo)) ? (lo) : (((v) > (hi)) ? (hi) : (v)))
@implementation ORKTrailmakingStepViewController {
ORKTrailmakingContentView *_trailmakingContentView;
NSArray *_testPoints;
ORKTrailMakingTypeIdentifier _trailType;
int _nextIndex;
int _errors;
NSMutableArray *_taps;
NSTimer *_updateTimer;
UILabel *_timerLabel;
}
- (instancetype)initWithStep:(ORKStep *)step {
self = [super initWithStep:step];
if (self) {
_testPoints = [self fetchRandomTest];
_taps = [NSMutableArray array];
if ([step isKindOfClass:[ORKTrailmakingStep class]]) {
_trailType = [((ORKTrailmakingStep*)step) trailType];
} else {
_trailType = ORKTrailMakingTypeIdentifierA;
}
}
return self;
}
- (void)initializeInternalButtonItems {
[super initializeInternalButtonItems];
// Don't show next button
self.internalContinueButtonItem = nil;
self.internalDoneButtonItem = nil;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_trailmakingContentView = [[ORKTrailmakingContentView alloc] initWithType:_trailType];
self.activeStepView.activeCustomView = _trailmakingContentView;
for (ORKRoundTappingButton* b in _trailmakingContentView.tapButtons) {
[b addTarget:self action:@selector(buttonPressed:forEvent:) forControlEvents:UIControlEventTouchDown];
}
_timerLabel = [[UILabel alloc] init];
_timerLabel.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:_timerLabel];
}
- (void)timerUpdated:(NSTimer*)timer {
NSTimeInterval elapsed = [[NSDate date] timeIntervalSinceDate: self.presentedDate];
NSString *text = [NSString localizedStringWithFormat:ORKLocalizedString(@"TRAILMAKING_TIMER", nil), elapsed];
if (_errors == 1) {
text = [NSString localizedStringWithFormat:ORKLocalizedString(@"TRAILMAKING_ERROR", nil), text, _errors];
} else if (_errors > 1) {
text = [NSString localizedStringWithFormat:ORKLocalizedString(@"TRAILMAKING_ERROR_PLURAL", nil), text, _errors];
}
_timerLabel.text = text;
}
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
CGRect screenRect = [[UIScreen mainScreen] bounds];
int screenSize = MAX(screenRect.size.width, screenRect.size.height);
int cx;
if (screenSize >= 736) {
cx = 50; // iPhone 6+/7+
} else if (screenSize >= 667) {
cx = 45; // iPhone 6/7
} else {
cx = 40; // iPhone 5/SE
}
CGRect labelRect = _trailmakingContentView.testArea;
labelRect.size.height = 20;
[_timerLabel setFrame:labelRect];
CGRect r = _trailmakingContentView.testArea;
int idx = 0;
for (ORKRoundTappingButton* b in _trailmakingContentView.tapButtons) {
CGPoint pp = [[_testPoints objectAtIndex:idx] CGPointValue];
if (r.size.width > r.size.height)
{
float temp = pp.x;
pp.x = pp.y;
pp.y = temp;
}
const int x = BOUND(5, r.size.width - cx - 5, pp.x * r.size.width);
const int y = BOUND(5, r.size.height - cx - 5, pp.y * r.size.height);
b.frame = CGRectMake(x, y, cx, cx);
b.diameter = cx;
idx++;
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self start];
_updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerUpdated:) userInfo:nil repeats:YES];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (_updateTimer != nil) {
[_updateTimer invalidate];
_updateTimer = nil;
}
}
- (IBAction)buttonPressed:(id)button forEvent:(UIEvent *)event {
NSUInteger buttonIndex = [_trailmakingContentView.tapButtons indexOfObject:button];
if (buttonIndex != NSNotFound) {
ORKTrailmakingTap* tap = [[ORKTrailmakingTap alloc] init];
tap.timestamp = [[NSDate date] timeIntervalSinceDate: self.presentedDate];
tap.index = buttonIndex;
if (buttonIndex == _nextIndex) {
_nextIndex++;
_trailmakingContentView.linesToDraw = _nextIndex - 1;
if (_nextIndex == _trailmakingContentView.tapButtons.count) {
[self performSelector:@selector(finish) withObject:nil afterDelay:1.5];
[_updateTimer invalidate];
_updateTimer = nil;
}
tap.incorrect = NO;
[_trailmakingContentView clearErrors];
} else {
_errors++;
tap.incorrect = YES;
[_trailmakingContentView clearErrors];
[_trailmakingContentView setError:(int)buttonIndex];
}
[_taps addObject:tap];
}
}
- (NSArray<NSString*>*)testData {
static NSArray<NSString*> *testData;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
testData = @[
@"0.819257,0.121951,0.603041,0.214286,0.182432,0.121951,0.231419,0.490418,0.177365,0.836237,0.478041,0.812718,0.398649,0.442509,0.565878,0.670732,0.652027,0.804878,0.827703,0.343206,0.604730,0.306620,0.633446,0.533101,0.283784,0.267422",
@"0.779661,0.907746,0.722034,0.190601,0.906780,0.395997,0.869492,0.063534,0.161017,0.060923,0.223729,0.328111,0.105085,0.879896,0.286441,0.799826,0.461017,0.830287,0.505085,0.580505,0.654237,0.800696,0.640678,0.461271,0.337288,0.533507",
@"0.824027,0.881533,0.604061,0.790941,0.186125,0.876307,0.231810,0.509582,0.177665,0.163763,0.485618,0.183798,0.401015,0.554007,0.571912,0.332753,0.659898,0.195993,0.830795,0.657665,0.604061,0.695993,0.634518,0.466899,0.291032,0.735192",
@"0.777403,0.092334,0.728499,0.808362,0.905565,0.602787,0.854975,0.935540,0.166948,0.934669,0.225970,0.670732,0.109612,0.123693,0.288364,0.203833,0.463744,0.169861,0.505902,0.420732,0.654300,0.202962,0.644182,0.540941,0.338954,0.469512",
@"0.487310,0.475610,0.318105,0.262195,0.763113,0.186411,0.560068,0.758711,0.521151,0.614111,0.270728,0.450348,0.390863,0.865854,0.089679,0.935540,0.142132,0.686411,0.138748,0.141986,0.514382,0.164634,0.906937,0.082753,0.896785,0.710801",
@"0.634518,0.369338,0.678511,0.827526,0.448393,0.370209,0.509306,0.751742,0.257191,0.797909,0.087986,0.912021,0.145516,0.223868,0.076142,0.055749,0.873096,0.100174,0.912014,0.514808,0.737733,0.230836,0.839256,0.935540,0.411168,0.941638",
@"0.483871,0.530078,0.315789,0.744551,0.758913,0.816042,0.555178,0.242371,0.516129,0.391456,0.263158,0.552746,0.385399,0.136879,0.083192,0.071491,0.135823,0.315606,0.139219,0.861377,0.514431,0.838710,0.903226,0.919791,0.893039,0.293810",
@"0.633446,0.633827,0.673986,0.176112,0.445946,0.632084,0.503378,0.251962,0.260135,0.205754,0.087838,0.088056,0.146959,0.780296,0.081081,0.949433,0.869932,0.903226,0.908784,0.485615,0.736486,0.770706,0.837838,0.066260,0.410473,0.061029",
@"0.505068,0.481707,0.263514,0.751742,0.728041,0.816202,0.618243,0.162892,0.538851,0.323171,0.255068,0.577526,0.361486,0.136760,0.116554,0.087108,0.136824,0.418118,0.119932,0.890244,0.479730,0.837108,0.869932,0.922474,0.859797,0.438153",
@"0.587838,0.630662,0.699324,0.148955,0.479730,0.519164,0.481419,0.155052,0.263514,0.183798,0.076014,0.123693,0.231419,0.722997,0.131757,0.913763,0.878378,0.898955,0.912162,0.533972,0.711149,0.798781,0.854730,0.056620,0.334459,0.056620",
@"0.501689,0.523560,0.256757,0.253054,0.724662,0.185864,0.616554,0.841187,0.535473,0.678883,0.256757,0.424084,0.358108,0.866492,0.111486,0.915358,0.133446,0.583770,0.118243,0.109948,0.478041,0.164049,0.868243,0.079407,0.854730,0.564572",
@"0.587140,0.370435,0.695431,0.851304,0.478849,0.481739,0.483926,0.845217,0.265651,0.817391,0.074450,0.873043,0.233503,0.274783,0.133672,0.087826,0.878173,0.103478,0.920474,0.467826,0.717428,0.202609,0.852792,0.942609,0.314721,0.946087"
];
});
return testData;
}
- (NSArray*)fetchRandomTest {
const int testNum = arc4random_uniform((uint32_t)[[self testData] count]);
const bool invertX = arc4random_uniform(2) == 1;
const bool invertY = arc4random_uniform(2) == 1;
const bool reverse = arc4random_uniform(2) == 1;
NSMutableArray* points = [NSMutableArray array];
NSString* testPointsStr = [self.testData objectAtIndex:testNum];
NSArray* chunks = [testPointsStr componentsSeparatedByString:@","];
for (int i = 0; i < chunks.count; i += 2) {
CGPoint pp;
pp.x = [[chunks objectAtIndex:i + 0] floatValue];
pp.y = [[chunks objectAtIndex:i + 1] floatValue];
if (invertX) pp.x = 1.0f - pp.x;
if (invertY) pp.y = 1.0f - pp.y;
[points addObject:[NSValue valueWithCGPoint:pp]];
}
return reverse ? [[points reverseObjectEnumerator] allObjects] : [points copy];
}
- (ORKStepResult *)result {
ORKStepResult *stepResult = [super result];
// "Now" is the end time of the result, which is either actually now,
// or the last time we were in the responder chain.
NSDate *now = stepResult.endDate;
NSMutableArray *results = [NSMutableArray arrayWithArray:stepResult.results];
ORKTrailmakingResult *trailmakingResult = [[ORKTrailmakingResult alloc] initWithIdentifier:self.step.identifier];
trailmakingResult.startDate = stepResult.startDate;
trailmakingResult.endDate = now;
trailmakingResult.taps = [_taps copy];
trailmakingResult.numberOfErrors = _errors;
[results addObject:trailmakingResult];
stepResult.results = [results copy];
return stepResult;
}
@end
@@ -51,7 +51,7 @@
NSLayoutConstraint *_topConstraint;
}
@property (nonatomic, strong, readonly) ORKProgressView *progressView;
@property (nonatomic, strong, readonly) ORKProgressView *progressView;
@end
@@ -89,6 +89,7 @@
- (void)setUpConstraints {
NSMutableArray *constraints = [NSMutableArray new];
NSDictionary *views = NSDictionaryOfVariableBindings(_progressView);
[constraints addObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_progressView]-(>=0)-|"
@@ -142,6 +143,7 @@
}
- (ORKWalkingTaskStep *)walkingTaskStep {
NSAssert(self.step == nil || [self.step isKindOfClass:[ORKWalkingTaskStep class]], @"Expected step subclass of ORKWalkingTaskStep");
return (ORKWalkingTaskStep *)self.step;
}
@@ -6,8 +6,13 @@
},
{
"idiom" : "iphone",
"scale" : "2x",
"filename" : "handtapping01@2x.png"
"subtype" : "retina4",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "handtapping01@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
@@ -16,8 +21,13 @@
},
{
"idiom" : "iphone",
"scale" : "3x",
"filename" : "handtapping01@3x.png"
"filename" : "handtapping01@3x.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"subtype" : "retina4",
"scale" : "3x"
},
{
"idiom" : "ipad",
@@ -25,8 +35,8 @@
},
{
"idiom" : "ipad",
"scale" : "2x",
"filename" : "handtapping01@2x~ipad.png"
"filename" : "handtapping01@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
@@ -6,8 +6,13 @@
},
{
"idiom" : "iphone",
"scale" : "2x",
"filename" : "handtapping02@2x.png"
"subtype" : "retina4",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "handtapping02@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
@@ -16,8 +21,13 @@
},
{
"idiom" : "iphone",
"scale" : "3x",
"filename" : "handtapping02@3x.png"
"filename" : "handtapping02@3x.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"subtype" : "retina4",
"scale" : "3x"
},
{
"idiom" : "ipad",
@@ -25,8 +35,8 @@
},
{
"idiom" : "ipad",
"scale" : "2x",
"filename" : "handtapping02@2x~ipad.png"
"filename" : "handtapping02@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
@@ -6,8 +6,13 @@
},
{
"idiom" : "iphone",
"scale" : "2x",
"filename" : "heart-fitness@2x.png"
"subtype" : "retina4",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "heart-fitness@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
@@ -16,8 +21,13 @@
},
{
"idiom" : "iphone",
"scale" : "3x",
"filename" : "heart-fitness@3x.png"
"filename" : "heart-fitness@3x.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"subtype" : "retina4",
"scale" : "3x"
},
{
"idiom" : "ipad",
@@ -25,8 +35,8 @@
},
{
"idiom" : "ipad",
"scale" : "2x",
"filename" : "heart-fitness@2x~ipad.png"
"filename" : "heart-fitness@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
@@ -6,8 +6,13 @@
},
{
"idiom" : "iphone",
"scale" : "2x",
"filename" : "heartbeat@2x.png"
"subtype" : "retina4",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "heartbeat@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
@@ -16,8 +21,13 @@
},
{
"idiom" : "iphone",
"scale" : "3x",
"filename" : "heartbeat@3x.png"
"filename" : "heartbeat@3x.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"subtype" : "retina4",
"scale" : "3x"
},
{
"idiom" : "ipad",
@@ -25,8 +35,8 @@
},
{
"idiom" : "ipad",
"scale" : "2x",
"filename" : "heartbeat@2x~ipad.png"
"filename" : "heartbeat@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
@@ -6,8 +6,13 @@
},
{
"idiom" : "iphone",
"scale" : "2x",
"filename" : "holepegtest1@2x.png"
"subtype" : "retina4",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "holepegtest1@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
@@ -16,8 +21,13 @@
},
{
"idiom" : "iphone",
"scale" : "3x",
"filename" : "holepegtest1@3x.png"
"filename" : "holepegtest1@3x.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"subtype" : "retina4",
"scale" : "3x"
},
{
"idiom" : "ipad",
@@ -25,8 +35,8 @@
},
{
"idiom" : "ipad",
"scale" : "2x",
"filename" : "holepegtest1@2x~ipad.png"
"filename" : "holepegtest1@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
@@ -6,8 +6,13 @@
},
{
"idiom" : "iphone",
"scale" : "2x",
"filename" : "holepegtest2@2x.png"
"subtype" : "retina4",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "holepegtest2@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
@@ -16,8 +21,13 @@
},
{
"idiom" : "iphone",
"scale" : "3x",
"filename" : "holepegtest2@3x.png"
"filename" : "holepegtest2@3x.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"subtype" : "retina4",
"scale" : "3x"
},
{
"idiom" : "ipad",
@@ -25,8 +35,8 @@
},
{
"idiom" : "ipad",
"scale" : "2x",
"filename" : "holepegtest2@2x~ipad.png"
"filename" : "holepegtest2@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
@@ -6,8 +6,13 @@
},
{
"idiom" : "iphone",
"scale" : "2x",
"filename" : "holepegtest3@2x.png"
"subtype" : "retina4",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "holepegtest3@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
@@ -16,8 +21,13 @@
},
{
"idiom" : "iphone",
"scale" : "3x",
"filename" : "holepegtest3@3x.png"
"filename" : "holepegtest3@3x.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"subtype" : "retina4",
"scale" : "3x"
},
{
"idiom" : "ipad",
@@ -25,8 +35,8 @@
},
{
"idiom" : "ipad",
"scale" : "2x",
"filename" : "holepegtest3@2x~ipad.png"
"filename" : "holepegtest3@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
@@ -4,6 +4,11 @@
"idiom" : "iphone",
"scale" : "1x"
},
{
"idiom" : "iphone",
"subtype" : "retina4",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "holepegtest4@2x.png",
@@ -19,6 +24,11 @@
"filename" : "holepegtest4@3x.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"subtype" : "retina4",
"scale" : "3x"
},
{
"idiom" : "ipad",
"scale" : "1x"
@@ -6,8 +6,13 @@
},
{
"idiom" : "iphone",
"scale" : "2x",
"filename" : "holepegtest5@2x.png"
"subtype" : "retina4",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "holepegtest5@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
@@ -16,8 +21,13 @@
},
{
"idiom" : "iphone",
"scale" : "3x",
"filename" : "holepegtest5@3x.png"
"filename" : "holepegtest5@3x.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"subtype" : "retina4",
"scale" : "3x"
},
{
"idiom" : "ipad",
@@ -25,8 +35,8 @@
},
{
"idiom" : "ipad",
"scale" : "2x",
"filename" : "holepegtest5@2x~ipad.png"
"filename" : "holepegtest5@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
@@ -6,8 +6,13 @@
},
{
"idiom" : "iphone",
"scale" : "2x",
"filename" : "holepegtest6@2x.png"
"subtype" : "retina4",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "holepegtest6@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
@@ -16,8 +21,13 @@
},
{
"idiom" : "iphone",
"scale" : "3x",
"filename" : "holepegtest6@3x.png"
"filename" : "holepegtest6@3x.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"subtype" : "retina4",
"scale" : "3x"
},
{
"idiom" : "ipad",
@@ -25,8 +35,8 @@
},
{
"idiom" : "ipad",
"scale" : "2x",
"filename" : "holepegtest6@2x~ipad.png"
"filename" : "holepegtest6@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
@@ -0,0 +1,31 @@
{
"images" : [
{
"idiom" : "iphone",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "knee_extended@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
"filename" : "knee_extended@3x.png",
"scale" : "3x"
},
{
"idiom" : "ipad",
"scale" : "1x"
},
{
"idiom" : "ipad",
"filename" : "knee_extended@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

@@ -0,0 +1,31 @@
{
"images" : [
{
"idiom" : "iphone",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "knee_extended@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
"filename" : "knee_extended@3x.png",
"scale" : "3x"
},
{
"idiom" : "ipad",
"scale" : "1x"
},
{
"idiom" : "ipad",
"filename" : "knee_extended@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

@@ -0,0 +1,31 @@
{
"images" : [
{
"idiom" : "iphone",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "knee_flexed@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
"scale" : "3x"
},
{
"idiom" : "ipad",
"filename" : "knee_flexed@3x.png",
"scale" : "1x"
},
{
"idiom" : "ipad",
"filename" : "knee_flexed@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

@@ -0,0 +1,31 @@
{
"images" : [
{
"idiom" : "iphone",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "knee_flexed@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
"filename" : "knee_flexed@3x.png",
"scale" : "3x"
},
{
"idiom" : "ipad",
"scale" : "1x"
},
{
"idiom" : "ipad",
"filename" : "knee_flexed@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

@@ -6,8 +6,13 @@
},
{
"idiom" : "iphone",
"scale" : "2x",
"filename" : "memory-second-screen@2x.png"
"subtype" : "retina4",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "memory-second-screen@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
@@ -16,8 +21,13 @@
},
{
"idiom" : "iphone",
"scale" : "3x",
"filename" : "memory-second-screen@3x.png"
"filename" : "memory-second-screen@3x.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"subtype" : "retina4",
"scale" : "3x"
},
{
"idiom" : "ipad",
@@ -25,8 +35,8 @@
},
{
"idiom" : "ipad",
"scale" : "2x",
"filename" : "memory-second-screen@2x~ipad.png"
"filename" : "memory-second-screen@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
@@ -6,8 +6,13 @@
},
{
"idiom" : "iphone",
"scale" : "2x",
"filename" : "phone-memory@2x.png"
"subtype" : "retina4",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "phone-memory@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
@@ -16,8 +21,13 @@
},
{
"idiom" : "iphone",
"scale" : "3x",
"filename" : "phone-memory@3x.png"
"filename" : "phone-memory@3x.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"subtype" : "retina4",
"scale" : "3x"
},
{
"idiom" : "ipad",
@@ -25,8 +35,8 @@
},
{
"idiom" : "ipad",
"scale" : "2x",
"filename" : "phone-memory@2x~ipad.png"
"filename" : "phone-memory@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {
@@ -6,8 +6,13 @@
},
{
"idiom" : "iphone",
"scale" : "2x",
"filename" : "phonefrequencywaves@2x.png"
"subtype" : "retina4",
"scale" : "1x"
},
{
"idiom" : "iphone",
"filename" : "phonefrequencywaves@2x.png",
"scale" : "2x"
},
{
"idiom" : "iphone",
@@ -16,8 +21,13 @@
},
{
"idiom" : "iphone",
"scale" : "3x",
"filename" : "phonefrequencywaves@3x.png"
"filename" : "phonefrequencywaves@3x.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"subtype" : "retina4",
"scale" : "3x"
},
{
"idiom" : "ipad",
@@ -25,8 +35,8 @@
},
{
"idiom" : "ipad",
"scale" : "2x",
"filename" : "phonefrequencywaves@2x~ipad.png"
"filename" : "phonefrequencywaves@2x~ipad.png",
"scale" : "2x"
}
],
"info" : {

Some files were not shown because too many files have changed in this diff Show More