diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 7e66273556..3243756ce4 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,5 +1,18 @@ # ResearchKit Release Notes +## ResearchKit 3.0.1 Release Notes +In addition to general stability and performance improvements, ResearchKit 3.0.1 includes the following updates: + +- **ORKFormStep** +The `ORKFormStep` has an additional property named `autoScrollEnabled` that allows developers to disable autoscrolling. + +- **ORKBodyItem** +The `ORKBodyItem` has an additional property named `alignImageToTop` that will align a body item's image and text to the top of each other. + +- **ORK3DModelStep** +An example of the `ORK3DModelStep` has been added to the ORKCatalog app. + + ## ResearchKit 3.0 Release Notes *ResearchKit 3.0* is a beta release diff --git a/ResearchKit.xcodeproj/project.pbxproj b/ResearchKit.xcodeproj/project.pbxproj index 72e1846f90..dacfc7e808 100644 --- a/ResearchKit.xcodeproj/project.pbxproj +++ b/ResearchKit.xcodeproj/project.pbxproj @@ -20,10 +20,12 @@ 03BD9EA4253E62A0008ADBE1 /* ORKBundleAsset.m in Sources */ = {isa = PBXBuildFile; fileRef = 03BD9EA2253E62A0008ADBE1 /* ORKBundleAsset.m */; }; 03EDD58024CA6B1D006245E9 /* ORKNotificationPermissionType.h in Headers */ = {isa = PBXBuildFile; fileRef = 03EDD57E24CA6B1D006245E9 /* ORKNotificationPermissionType.h */; settings = {ATTRIBUTES = (Public, ); }; }; 03EDD58124CA6B1D006245E9 /* ORKNotificationPermissionType.m in Sources */ = {isa = PBXBuildFile; fileRef = 03EDD57F24CA6B1D006245E9 /* ORKNotificationPermissionType.m */; }; + 0B0852742BD872C400149963 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 0B0852732BD872C400149963 /* PrivacyInfo.xcprivacy */; }; + 0B0852762BD872D800149963 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 0B0852752BD872D800149963 /* PrivacyInfo.xcprivacy */; }; + 0B0852782BD872EA00149963 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 0B0852772BD872EA00149963 /* PrivacyInfo.xcprivacy */; }; + 0B53DA642BD0595100227126 /* ResearchKitUI.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0B53DA622BD0595100227126 /* ResearchKitUI.strings */; }; 0B59A6BF28C1738D005035B4 /* ORKPickerTestDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B59A6BE28C1738D005035B4 /* ORKPickerTestDelegate.m */; }; 0B9A990F2A8AC47500D64C40 /* NSObject+TestingSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B9A990E2A8AC47500D64C40 /* NSObject+TestingSupport.m */; }; - 0B9CC5672A68C02C00080E29 /* UIImageView+ResearchKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B9CC5652A68C02C00080E29 /* UIImageView+ResearchKit.h */; }; - 0B9CC5682A68C02C00080E29 /* UIImageView+ResearchKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B9CC5662A68C02C00080E29 /* UIImageView+ResearchKit.m */; }; 0BD9B60D2B75991B00A64EF9 /* Sentence1.wav in Resources */ = {isa = PBXBuildFile; fileRef = 7118AC6620BF6A3A00D7A6BB /* Sentence1.wav */; }; 0BD9B60E2B75991F00A64EF9 /* Sentence2.wav in Resources */ = {isa = PBXBuildFile; fileRef = 7118AC6520BF6A3A00D7A6BB /* Sentence2.wav */; }; 0BD9B60F2B75992200A64EF9 /* Sentence3.wav in Resources */ = {isa = PBXBuildFile; fileRef = 7118AC6420BF6A3A00D7A6BB /* Sentence3.wav */; }; @@ -181,7 +183,13 @@ 5192BF992AE1D876006E43FB /* ORKChoiceViewCell+ORKTextChoice.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B8444632A79C25000292DEA /* ORKChoiceViewCell+ORKTextChoice.h */; }; 5192BF9A2AE1D8A4006E43FB /* ORKChoiceViewCell+ORKTextChoice.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B8444642A79C25000292DEA /* ORKChoiceViewCell+ORKTextChoice.m */; }; 5192BFA12AEAD7B5006E43FB /* Artwork.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 861610BF1A8D8EDD00245F7A /* Artwork.xcassets */; }; - 5192BFA92AEC4734006E43FB /* (null) in Sources */ = {isa = PBXBuildFile; }; + 51A11F172BD08D5E0060C07E /* HKSample+ORKJSONDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 51A11F132BD08D5D0060C07E /* HKSample+ORKJSONDictionary.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 51A11F182BD08D5E0060C07E /* CMMotionActivity+ORKJSONDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 51A11F142BD08D5D0060C07E /* CMMotionActivity+ORKJSONDictionary.m */; }; + 51A11F192BD08D5E0060C07E /* HKSample+ORKJSONDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 51A11F152BD08D5D0060C07E /* HKSample+ORKJSONDictionary.m */; }; + 51A11F1A2BD08D5E0060C07E /* CMMotionActivity+ORKJSONDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 51A11F162BD08D5E0060C07E /* CMMotionActivity+ORKJSONDictionary.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 51A11F222BD152660060C07E /* ORKActiveStepCustomView.h in Headers */ = {isa = PBXBuildFile; fileRef = 51A11F202BD152660060C07E /* ORKActiveStepCustomView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 51A11F232BD152660060C07E /* ORKActiveStepCustomView.m in Sources */ = {isa = PBXBuildFile; fileRef = 51A11F212BD152660060C07E /* ORKActiveStepCustomView.m */; }; + 51A11F242BD1548C0060C07E /* UIImageView+ResearchKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B9CC5662A68C02C00080E29 /* UIImageView+ResearchKit.m */; }; 51AEAAB22B744AC200F4D107 /* ORKQuestionStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 51AEAAA82B743FA500F4D107 /* ORKQuestionStepViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 51AEAAB32B744ACC00F4D107 /* ORKQuestionStepViewController_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 51AEAAA72B743FA500F4D107 /* ORKQuestionStepViewController_Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; 51AEAAB42B744B5700F4D107 /* ORKQuestionStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 51AEAAA62B743FA500F4D107 /* ORKQuestionStepViewController.m */; }; @@ -236,12 +244,19 @@ 51F716D1297E2CC400D8ACF7 /* ORKConsentLearnMoreViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F716CD297E2CB600D8ACF7 /* ORKConsentLearnMoreViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 51F716D3297E2FB600D8ACF7 /* ORKConsentLearnMoreViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 51F716CE297E2CB600D8ACF7 /* ORKConsentLearnMoreViewController.m */; }; 51F716EB2981B49000D8ACF7 /* ORKSpeechInNoiseStepViewController_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F716E82981AF1200D8ACF7 /* ORKSpeechInNoiseStepViewController_Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 51FBAC5D2BC9CE4A009CA28F /* ORKBorderedButton_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 51FBAC5C2BC9CE4A009CA28F /* ORKBorderedButton_Internal.h */; }; + 51FBAC902BD07333009CA28F /* UIImageView+ResearchKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B9CC5652A68C02C00080E29 /* UIImageView+ResearchKit.h */; }; 5D04884C25EF4CC30006C68B /* ORKQuestionStep_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D04884B25EF4CC30006C68B /* ORKQuestionStep_Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5D04885725F19A7A0006C68B /* ORKDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D04885525F19A7A0006C68B /* ORKDevice.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5D04885825F19A7A0006C68B /* ORKDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D04885625F19A7A0006C68B /* ORKDevice.m */; }; 5D04885C25F1B3AB0006C68B /* ORKDevice_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D04885B25F1B3AB0006C68B /* ORKDevice_Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5D43C5D424255675006F4084 /* ORKBodyItem_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D43C5D324255675006F4084 /* ORKBodyItem_Internal.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5DABE5AE24DA173F00570C57 /* ResearchKit_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 5DABE5AD24DA16E600570C57 /* ResearchKit_Prefix.pch */; }; + 5E6AB7DF2BC86900009ED0D5 /* ORKTaskViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E6AB7DE2BC86900009ED0D5 /* ORKTaskViewControllerTests.swift */; }; + 5EB91CC62BCE2ED500BBF23E /* ORKActiveStepQuantityView.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40AFB1A8D7C5B00081FAC /* ORKActiveStepQuantityView.m */; }; + 5EB91CC72BCE2EE600BBF23E /* ORKActiveStepView.m in Sources */ = {isa = PBXBuildFile; fileRef = 86AD910F1AB7B8A600361FEB /* ORKActiveStepView.m */; }; + 5EB91CC82BCE2EFD00BBF23E /* splMeter_sensitivity_offset.plist in Resources */ = {isa = PBXBuildFile; fileRef = 71F3B27F21001DEC00FB1C41 /* splMeter_sensitivity_offset.plist */; }; + 5EB91CC92BCE2F1D00BBF23E /* SentencesList.txt in Resources */ = {isa = PBXBuildFile; fileRef = BA22F76C20C4F884006E6E11 /* SentencesList.txt */; }; 714080DB235FD14700281E04 /* ResearchKit.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 714080D9235FD14700281E04 /* ResearchKit.stringsdict */; }; 714151D0225C4A23002CA33B /* ORKPasscodeViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14A92C6922444F93007547F2 /* ORKPasscodeViewControllerTests.swift */; }; 7141EA2222EFBC0C00650145 /* ORKLoggingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7141EA2122EFBC0C00650145 /* ORKLoggingTests.m */; }; @@ -561,7 +576,7 @@ CAA20D7A288B3D9100EDC764 /* ORKTextChoiceCellGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 861D11B31AA7D073003C98A7 /* ORKTextChoiceCellGroup.h */; settings = {ATTRIBUTES = (Public, ); }; }; CAA20D7B288B3D9100EDC764 /* ORKSurveyAnswerCellForImageSelection.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40BC61A8D7C5C00081FAC /* ORKSurveyAnswerCellForImageSelection.m */; }; CAA20D7C288B3D9100EDC764 /* ORKSurveyAnswerCellForSES.h in Headers */ = {isa = PBXBuildFile; fileRef = BAC2B65522F252F70079304E /* ORKSurveyAnswerCellForSES.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CAA20D7D288B3D9100EDC764 /* ORKSurveyCardHeaderView.h in Headers */ = {isa = PBXBuildFile; fileRef = BABBB19B2093299A00CB29E5 /* ORKSurveyCardHeaderView.h */; }; + CAA20D7D288B3D9100EDC764 /* ORKSurveyCardHeaderView.h in Headers */ = {isa = PBXBuildFile; fileRef = BABBB19B2093299A00CB29E5 /* ORKSurveyCardHeaderView.h */; settings = {ATTRIBUTES = (Public, ); }; }; CAA20D7E288B3D9100EDC764 /* ORKPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 865EA1671ABA1AA10037C68E /* ORKPicker.m */; }; CAA20D7F288B3D9100EDC764 /* SwiftUIViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519C298026D027AB00FD5F44 /* SwiftUIViewFactory.swift */; }; CAA20D80288B3D9100EDC764 /* ORKFormSectionTitleLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C40B801A8D7C5C00081FAC /* ORKFormSectionTitleLabel.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -698,7 +713,6 @@ CAA20E0E288B3E8200EDC764 /* ORKPasscodeStepView.h in Headers */ = {isa = PBXBuildFile; fileRef = 24A4DA0E1B8D0F21009C797A /* ORKPasscodeStepView.h */; }; CAA20E0F288B3E8200EDC764 /* ORKReviewStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BF91559A1BDE8D7D007FA459 /* ORKReviewStepViewController.m */; }; CAA20E10288B3E8200EDC764 /* ORKCustomSignatureFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = F7EC216524787338000C1F46 /* ORKCustomSignatureFooterView.m */; }; - CAA20E11288B3E8200EDC764 /* ORKCustomStepView_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C40B791A8D7C5C00081FAC /* ORKCustomStepView_Internal.h */; settings = {ATTRIBUTES = (Public, ); }; }; CAA20E12288B3E8200EDC764 /* ORKPasscodeStepView.m in Sources */ = {isa = PBXBuildFile; fileRef = 24A4DA0F1B8D0F21009C797A /* ORKPasscodeStepView.m */; }; CAA20E13288B3E8200EDC764 /* ORKWebViewStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 8419D6701FB73EC60088D7E5 /* ORKWebViewStepViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; CAA20E14288B3E8200EDC764 /* ORKInstructionStepContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = BADA2F25225DA54B005D2255 /* ORKInstructionStepContainerView.m */; }; @@ -765,10 +779,6 @@ CAA20E5D288B3E9900EDC764 /* UIResponder+ResearchKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40BEA1A8D7C5C00081FAC /* UIResponder+ResearchKit.m */; }; CAA20E5E288B3E9900EDC764 /* UIBarButtonItem+ORKBarButtonItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C40BE71A8D7C5C00081FAC /* UIBarButtonItem+ORKBarButtonItem.h */; settings = {ATTRIBUTES = (Public, ); }; }; CAA20E5F288B3E9900EDC764 /* UIBarButtonItem+ORKBarButtonItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40BE81A8D7C5C00081FAC /* UIBarButtonItem+ORKBarButtonItem.m */; }; - CAA20E7C288B3F1100EDC764 /* ORKActiveStepView.m in Sources */ = {isa = PBXBuildFile; fileRef = 86AD910F1AB7B8A600361FEB /* ORKActiveStepView.m */; }; - CAA20E8C288B3F1100EDC764 /* splMeter_sensitivity_offset.plist in Resources */ = {isa = PBXBuildFile; fileRef = 71F3B27F21001DEC00FB1C41 /* splMeter_sensitivity_offset.plist */; }; - CAA20EEA288B3F1200EDC764 /* ORKActiveStepQuantityView.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40AFB1A8D7C5B00081FAC /* ORKActiveStepQuantityView.m */; }; - CAA20F1A288B3F4000EDC764 /* SentencesList.txt in Resources */ = {isa = PBXBuildFile; fileRef = BA22F76C20C4F884006E6E11 /* SentencesList.txt */; }; CAA20F2A288B3F5B00EDC764 /* ORKConsentSharingStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = B11C549C1A9EF4A700265E61 /* ORKConsentSharingStepViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; CAA20F2E288B3F5B00EDC764 /* ORKConsentReviewStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40BFA1A8D7C5C00081FAC /* ORKConsentReviewStepViewController.m */; }; CAA20F30288B3F5B00EDC764 /* ORKConsentSharingStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B11C549D1A9EF4A700265E61 /* ORKConsentSharingStepViewController.m */; }; @@ -838,14 +848,10 @@ CAD08A38289DE5EC007B2A98 /* ORKDeviceMotionRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40B401A8D7C5B00081FAC /* ORKDeviceMotionRecorder.m */; }; CAD08A39289DE5F0007B2A98 /* CMDeviceMotion+ORKJSONDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C40B261A8D7C5B00081FAC /* CMDeviceMotion+ORKJSONDictionary.h */; }; CAD08A3A289DE5F3007B2A98 /* CMDeviceMotion+ORKJSONDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40B271A8D7C5B00081FAC /* CMDeviceMotion+ORKJSONDictionary.m */; }; - CAD08A3B289DE5F6007B2A98 /* CMMotionActivity+ORKJSONDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C40B281A8D7C5B00081FAC /* CMMotionActivity+ORKJSONDictionary.h */; }; - CAD08A3C289DE5F9007B2A98 /* CMMotionActivity+ORKJSONDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40B291A8D7C5B00081FAC /* CMMotionActivity+ORKJSONDictionary.m */; }; CAD08A3D289DE609007B2A98 /* ORKHealthClinicalTypeRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 71D8EF1520B9EE1900EBCDC6 /* ORKHealthClinicalTypeRecorder.h */; settings = {ATTRIBUTES = (Private, ); }; }; CAD08A3E289DE60E007B2A98 /* ORKHealthClinicalTypeRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 71D8EF1620B9EE1900EBCDC6 /* ORKHealthClinicalTypeRecorder.m */; }; CAD08A3F289DE611007B2A98 /* ORKHealthQuantityTypeRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C40B411A8D7C5B00081FAC /* ORKHealthQuantityTypeRecorder.h */; settings = {ATTRIBUTES = (Private, ); }; }; CAD08A40289DE615007B2A98 /* ORKHealthQuantityTypeRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40B421A8D7C5B00081FAC /* ORKHealthQuantityTypeRecorder.m */; }; - CAD08A41289DE617007B2A98 /* HKSample+ORKJSONDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C40B2C1A8D7C5B00081FAC /* HKSample+ORKJSONDictionary.h */; }; - CAD08A42289DE61A007B2A98 /* HKSample+ORKJSONDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40B2D1A8D7C5B00081FAC /* HKSample+ORKJSONDictionary.m */; }; CAD08A43289DE620007B2A98 /* ORKLocationRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C40B431A8D7C5B00081FAC /* ORKLocationRecorder.h */; settings = {ATTRIBUTES = (Private, ); }; }; CAD08A44289DE623007B2A98 /* ORKLocationRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40B441A8D7C5B00081FAC /* ORKLocationRecorder.m */; }; CAD08A45289DE626007B2A98 /* CLLocation+ORKJSONDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C40B221A8D7C5B00081FAC /* CLLocation+ORKJSONDictionary.h */; }; @@ -1052,6 +1058,10 @@ 03EDD57E24CA6B1D006245E9 /* ORKNotificationPermissionType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ORKNotificationPermissionType.h; sourceTree = ""; }; 03EDD57F24CA6B1D006245E9 /* ORKNotificationPermissionType.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ORKNotificationPermissionType.m; sourceTree = ""; }; 05F3765923C797930068E166 /* ResearchKit.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = ResearchKit.xctestplan; sourceTree = ""; }; + 0B0852732BD872C400149963 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; + 0B0852752BD872D800149963 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; + 0B0852772BD872EA00149963 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; + 0B53DA632BD0595100227126 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/ResearchKitUI.strings; sourceTree = ""; }; 0B59A6BD28C1738D005035B4 /* ORKPickerTestDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ORKPickerTestDelegate.h; sourceTree = ""; }; 0B59A6BE28C1738D005035B4 /* ORKPickerTestDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ORKPickerTestDelegate.m; sourceTree = ""; }; 0B8444632A79C25000292DEA /* ORKChoiceViewCell+ORKTextChoice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ORKChoiceViewCell+ORKTextChoice.h"; sourceTree = ""; }; @@ -1334,6 +1344,12 @@ 5192BF962AE1C5A1006E43FB /* ORKAnswerFormat+FormStepViewControllerAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ORKAnswerFormat+FormStepViewControllerAdditions.m"; sourceTree = ""; }; 519C298026D027AB00FD5F44 /* SwiftUIViewFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIViewFactory.swift; sourceTree = ""; }; 519C298D26D027E500FD5F44 /* TextChoiceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextChoiceView.swift; sourceTree = ""; }; + 51A11F132BD08D5D0060C07E /* HKSample+ORKJSONDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HKSample+ORKJSONDictionary.h"; sourceTree = ""; }; + 51A11F142BD08D5D0060C07E /* CMMotionActivity+ORKJSONDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CMMotionActivity+ORKJSONDictionary.m"; sourceTree = ""; }; + 51A11F152BD08D5D0060C07E /* HKSample+ORKJSONDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "HKSample+ORKJSONDictionary.m"; sourceTree = ""; }; + 51A11F162BD08D5E0060C07E /* CMMotionActivity+ORKJSONDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CMMotionActivity+ORKJSONDictionary.h"; sourceTree = ""; }; + 51A11F202BD152660060C07E /* ORKActiveStepCustomView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ORKActiveStepCustomView.h; sourceTree = ""; }; + 51A11F212BD152660060C07E /* ORKActiveStepCustomView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ORKActiveStepCustomView.m; sourceTree = ""; }; 51AEAAA62B743FA500F4D107 /* ORKQuestionStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKQuestionStepViewController.m; sourceTree = ""; }; 51AEAAA72B743FA500F4D107 /* ORKQuestionStepViewController_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKQuestionStepViewController_Private.h; sourceTree = ""; }; 51AEAAA82B743FA500F4D107 /* ORKQuestionStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKQuestionStepViewController.h; sourceTree = ""; }; @@ -1381,6 +1397,11 @@ 51F716CD297E2CB600D8ACF7 /* ORKConsentLearnMoreViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKConsentLearnMoreViewController.h; path = ResearchKitUI/Stale/ORKConsentLearnMoreViewController.h; sourceTree = SOURCE_ROOT; }; 51F716CE297E2CB600D8ACF7 /* ORKConsentLearnMoreViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKConsentLearnMoreViewController.m; path = ResearchKitUI/Stale/ORKConsentLearnMoreViewController.m; sourceTree = SOURCE_ROOT; }; 51F716E82981AF1200D8ACF7 /* ORKSpeechInNoiseStepViewController_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ORKSpeechInNoiseStepViewController_Private.h; sourceTree = ""; }; + 51FBAC572BC85C7A009CA28F /* ResearchKit_Private.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = ResearchKit_Private.modulemap; sourceTree = ""; }; + 51FBAC582BC86E6E009CA28F /* ResearchKitUI_Private.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = ResearchKitUI_Private.modulemap; sourceTree = ""; }; + 51FBAC592BC998D8009CA28F /* ResearchKitActiveTask_Private.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = ResearchKitActiveTask_Private.modulemap; sourceTree = ""; }; + 51FBAC5C2BC9CE4A009CA28F /* ORKBorderedButton_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ORKBorderedButton_Internal.h; sourceTree = ""; }; + 51FBAC7D2BC9EBA7009CA28F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5D000EC22620F27100E5442A /* ResearchKit-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "ResearchKit-Debug.xcconfig"; sourceTree = ""; }; 5D000EC42620F27100E5442A /* ResearchKit-Shared.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "ResearchKit-Shared.xcconfig"; sourceTree = ""; }; 5D000EC62620F27100E5442A /* ResearchKit-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "ResearchKit-Release.xcconfig"; sourceTree = ""; }; @@ -1411,6 +1432,7 @@ 5D5880372410394E005B3D91 /* ORKSpeechInNoiseResult.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ORKSpeechInNoiseResult.h; sourceTree = ""; }; 5D5880382410394E005B3D91 /* ORKSpeechInNoiseResult.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ORKSpeechInNoiseResult.m; sourceTree = ""; }; 5DABE5AD24DA16E600570C57 /* ResearchKit_Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ResearchKit_Prefix.pch; sourceTree = ""; }; + 5E6AB7DE2BC86900009ED0D5 /* ORKTaskViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ORKTaskViewControllerTests.swift; sourceTree = ""; }; 6146D0A11B84A91E0068491D /* ORKGraphChartAccessibilityElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKGraphChartAccessibilityElement.h; sourceTree = ""; }; 6146D0A21B84A91E0068491D /* ORKGraphChartAccessibilityElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKGraphChartAccessibilityElement.m; sourceTree = ""; }; 618DA0481A93D0D600E63AA8 /* ORKAccessibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKAccessibility.h; sourceTree = ""; }; @@ -1561,12 +1583,8 @@ 86C40B251A8D7C5B00081FAC /* CMAccelerometerData+ORKJSONDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = "CMAccelerometerData+ORKJSONDictionary.m"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 86C40B261A8D7C5B00081FAC /* CMDeviceMotion+ORKJSONDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "CMDeviceMotion+ORKJSONDictionary.h"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 86C40B271A8D7C5B00081FAC /* CMDeviceMotion+ORKJSONDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = "CMDeviceMotion+ORKJSONDictionary.m"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 86C40B281A8D7C5B00081FAC /* CMMotionActivity+ORKJSONDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "CMMotionActivity+ORKJSONDictionary.h"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - 86C40B291A8D7C5B00081FAC /* CMMotionActivity+ORKJSONDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = "CMMotionActivity+ORKJSONDictionary.m"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 86C40B2A1A8D7C5B00081FAC /* CMPedometerData+ORKJSONDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "CMPedometerData+ORKJSONDictionary.h"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 86C40B2B1A8D7C5B00081FAC /* CMPedometerData+ORKJSONDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = "CMPedometerData+ORKJSONDictionary.m"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 86C40B2C1A8D7C5B00081FAC /* HKSample+ORKJSONDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "HKSample+ORKJSONDictionary.h"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - 86C40B2D1A8D7C5B00081FAC /* HKSample+ORKJSONDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = "HKSample+ORKJSONDictionary.m"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 86C40B2E1A8D7C5B00081FAC /* ORKAccelerometerRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ORKAccelerometerRecorder.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 86C40B2F1A8D7C5B00081FAC /* ORKAccelerometerRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ORKAccelerometerRecorder.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 86C40B301A8D7C5B00081FAC /* ORKActiveStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKActiveStep.h; sourceTree = ""; }; @@ -1636,7 +1654,6 @@ 86C40B761A8D7C5C00081FAC /* ORKCountdownLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKCountdownLabel.m; sourceTree = ""; }; 86C40B771A8D7C5C00081FAC /* ORKCustomStepView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKCustomStepView.h; sourceTree = ""; }; 86C40B781A8D7C5C00081FAC /* ORKCustomStepView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ORKCustomStepView.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 86C40B791A8D7C5C00081FAC /* ORKCustomStepView_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKCustomStepView_Internal.h; sourceTree = ""; }; 86C40B7A1A8D7C5C00081FAC /* ORKDefaultFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKDefaultFont.h; sourceTree = ""; }; 86C40B7B1A8D7C5C00081FAC /* ORKDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKDefines.h; sourceTree = ""; }; 86C40B7C1A8D7C5C00081FAC /* ORKHelpers_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKHelpers_Private.h; sourceTree = ""; }; @@ -2113,6 +2130,15 @@ name = "Custom Step"; sourceTree = ""; }; + 0B53DA612BD0590700227126 /* Localized */ = { + isa = PBXGroup; + children = ( + 0B53DA622BD0595100227126 /* ResearchKitUI.strings */, + ); + name = Localized; + path = Accessibility/Localized; + sourceTree = ""; + }; 0BCC4BA4286A654C001E316F /* Resources */ = { isa = PBXGroup; children = ( @@ -2139,6 +2165,7 @@ 14A92C6922444F93007547F2 /* ORKPasscodeViewControllerTests.swift */, 148E58BC227B36DB00EEF915 /* ORKCompletionStepViewControllerTests.swift */, 0324C1D725439E1800BBE77B /* ORKVideoInstructionStepViewControllerTests.swift */, + 5E6AB7DE2BC86900009ED0D5 /* ORKTaskViewControllerTests.swift */, ); name = ORKViewControllerTests; sourceTree = ""; @@ -2452,6 +2479,15 @@ path = Normalized; sourceTree = ""; }; + 51A11F1B2BD094A00060C07E /* Custom View */ = { + isa = PBXGroup; + children = ( + 51A11F202BD152660060C07E /* ORKActiveStepCustomView.h */, + 51A11F212BD152660060C07E /* ORKActiveStepCustomView.m */, + ); + path = "Custom View"; + sourceTree = ""; + }; 51AEAAA02B74296800F4D107 /* Stale */ = { isa = PBXGroup; children = ( @@ -2648,6 +2684,7 @@ 5D06632E24FEF272005D9B40 /* ResearchKitUI */ = { isa = PBXGroup; children = ( + 0B53DA612BD0590700227126 /* Localized */, 51AEAAA52B743EE000F4D107 /* Stale */, CA1C7A6F288B18B8004DAB3A /* Common */, CA1C7ABE288B3786004DAB3A /* Onboarding */, @@ -2655,8 +2692,10 @@ 5D06632F24FEF272005D9B40 /* ResearchKitUI.h */, CA6A0D9F288F1F3C0048C1EF /* ResearchKitUI.modulemap */, CA6A0D9D288F1BDC0048C1EF /* ResearchKitUI_Private.h */, + 0B0852752BD872D800149963 /* PrivacyInfo.xcprivacy */, 5D06633024FEF272005D9B40 /* Info.plist */, CA1C7A5B288B0C69004DAB3A /* Info-iOS.plist */, + 51FBAC582BC86E6E009CA28F /* ResearchKitUI_Private.modulemap */, ); path = ResearchKitUI; sourceTree = ""; @@ -2676,6 +2715,10 @@ 866DA5121D63D01C00C9AF3F /* DataCollection */ = { isa = PBXGroup; children = ( + 51A11F162BD08D5E0060C07E /* CMMotionActivity+ORKJSONDictionary.h */, + 51A11F142BD08D5D0060C07E /* CMMotionActivity+ORKJSONDictionary.m */, + 51A11F132BD08D5D0060C07E /* HKSample+ORKJSONDictionary.h */, + 51A11F152BD08D5D0060C07E /* HKSample+ORKJSONDictionary.m */, 866DA5131D63D04700C9AF3F /* ORKCollector_Internal.h */, 866DA5141D63D04700C9AF3F /* ORKCollector.h */, 866DA5151D63D04700C9AF3F /* ORKCollector.m */, @@ -2710,6 +2753,8 @@ B1C0F4E01A9BA65F0022C153 /* Localized */, 86C40C101A8D7C5C00081FAC /* Info.plist */, B18AABE01A9F08D9003871B5 /* ResearchKit.modulemap */, + 51FBAC572BC85C7A009CA28F /* ResearchKit_Private.modulemap */, + 0B0852732BD872C400149963 /* PrivacyInfo.xcprivacy */, 861610BF1A8D8EDD00245F7A /* Artwork.xcassets */, ); path = ResearchKit; @@ -3294,6 +3339,7 @@ CA1C7A72288B1A75004DAB3A /* Skin */ = { isa = PBXGroup; children = ( + 51FBAC5C2BC9CE4A009CA28F /* ORKBorderedButton_Internal.h */, 0B8444632A79C25000292DEA /* ORKChoiceViewCell+ORKTextChoice.h */, 0B8444642A79C25000292DEA /* ORKChoiceViewCell+ORKTextChoice.m */, 86C40B6B1A8D7C5B00081FAC /* ORKBodyLabel.h */, @@ -3379,7 +3425,6 @@ 86C40BBE1A8D7C5C00081FAC /* ORKStepViewController_Internal.h */, 86C40B771A8D7C5C00081FAC /* ORKCustomStepView.h */, 86C40B781A8D7C5C00081FAC /* ORKCustomStepView.m */, - 86C40B791A8D7C5C00081FAC /* ORKCustomStepView_Internal.h */, CA1C7A75288B1C41004DAB3A /* Request Permissions Step */, CA1C7A77288B1CB6004DAB3A /* Instruction Step */, CA1C7A7C288B1DB2004DAB3A /* Form Step */, @@ -3745,6 +3790,7 @@ CAD08969289DD747007B2A98 /* ResearchKitActiveTask.h */, CAFAA6C128A198BD0010BBDE /* ResearchKitActiveTask_Private.h */, CAFAA6C328A199950010BBDE /* ResearchKitActiveTask.modulemap */, + 51FBAC592BC998D8009CA28F /* ResearchKitActiveTask_Private.modulemap */, CA954B6D28AD8A8C0020A35C /* ORKStep+ResearchKitActiveTask.m */, 5156C9BF2B7E421400983535 /* Touch Ability */, CA2B902A28A18ED00025B773 /* Front Facing Camera */, @@ -3768,6 +3814,8 @@ CAD089A5289DDE87007B2A98 /* TowerOfHanoi */, CAD089A6289DDE97007B2A98 /* Trailmaking */, CAD089A7289DDEA8007B2A98 /* Walking */, + 51FBAC7D2BC9EBA7009CA28F /* Info.plist */, + 0B0852772BD872EA00149963 /* PrivacyInfo.xcprivacy */, ); path = ResearchKitActiveTask; sourceTree = ""; @@ -3905,6 +3953,7 @@ CAD08986289DDB46007B2A98 /* Common */ = { isa = PBXGroup; children = ( + 51A11F1B2BD094A00060C07E /* Custom View */, CAD08987289DDB59007B2A98 /* Touch Anywhere Step */, CAD08988289DDB80007B2A98 /* Active Step */, CAD0898C289DDBDC007B2A98 /* Countdown Step */, @@ -4037,8 +4086,6 @@ 71D8EF1620B9EE1900EBCDC6 /* ORKHealthClinicalTypeRecorder.m */, 86C40B411A8D7C5B00081FAC /* ORKHealthQuantityTypeRecorder.h */, 86C40B421A8D7C5B00081FAC /* ORKHealthQuantityTypeRecorder.m */, - 86C40B2C1A8D7C5B00081FAC /* HKSample+ORKJSONDictionary.h */, - 86C40B2D1A8D7C5B00081FAC /* HKSample+ORKJSONDictionary.m */, ); path = Health; sourceTree = ""; @@ -4050,8 +4097,6 @@ 86C40B401A8D7C5B00081FAC /* ORKDeviceMotionRecorder.m */, 86C40B261A8D7C5B00081FAC /* CMDeviceMotion+ORKJSONDictionary.h */, 86C40B271A8D7C5B00081FAC /* CMDeviceMotion+ORKJSONDictionary.m */, - 86C40B281A8D7C5B00081FAC /* CMMotionActivity+ORKJSONDictionary.h */, - 86C40B291A8D7C5B00081FAC /* CMMotionActivity+ORKJSONDictionary.m */, ); path = "Device Motion"; sourceTree = ""; @@ -4465,6 +4510,7 @@ 51E03D682491A601008F8406 /* ORKHealthKitPermissionType.h in Headers */, FF919A5F1E81CF07005C2A1E /* ORKVideoInstructionStepResult.h in Headers */, 866DA5201D63D04700C9AF3F /* ORKCollector.h in Headers */, + 51A11F1A2BD08D5E0060C07E /* CMMotionActivity+ORKJSONDictionary.h in Headers */, BF91559B1BDE8D7D007FA459 /* ORKReviewStep_Internal.h in Headers */, FF919A561E81BEE0005C2A1E /* ORKCollectionResult_Private.h in Headers */, FF919A661E81D168005C2A1E /* ORKSignatureResult_Private.h in Headers */, @@ -4537,8 +4583,8 @@ 86C40D301A8D7C5C00081FAC /* ORKHealthAnswerFormat.h in Headers */, 7167D028231B1EAA00AAB4DD /* ORKFormStep_Internal.h in Headers */, FF5CA6121D2C2670001660A3 /* ORKTableStep.h in Headers */, - 0B9CC5672A68C02C00080E29 /* UIImageView+ResearchKit.h in Headers */, FA7A9D2F1B083DD3005A2BEA /* ORKConsentSectionFormatter.h in Headers */, + 51A11F172BD08D5E0060C07E /* HKSample+ORKJSONDictionary.h in Headers */, 86C40D561A8D7C5C00081FAC /* ORKOrderedTask.h in Headers */, FF5051F01D66908C0065E677 /* ORKNavigablePageStep.h in Headers */, BC13CE401B0666FD0044153C /* ORKResultPredicate.h in Headers */, @@ -4582,6 +4628,7 @@ CAA20F34288B3F6700EDC764 /* ORKVerificationStepViewController.h in Headers */, CAA20E1F288B3E8200EDC764 /* ORKPasscodeStepViewController.h in Headers */, CAA20E39288B3E8200EDC764 /* ORKFormStepViewController.h in Headers */, + 51FBAC5D2BC9CE4A009CA28F /* ORKBorderedButton_Internal.h in Headers */, CAA20E37288B3E8200EDC764 /* ORKRequestPermissionsStepViewController.h in Headers */, CAA20F37288B3F6700EDC764 /* ORKVerificationStepView.h in Headers */, CAA20D7A288B3D9100EDC764 /* ORKTextChoiceCellGroup.h in Headers */, @@ -4706,6 +4753,7 @@ CAA20D8E288B3D9100EDC764 /* ORKSurveyAnswerCellForText.h in Headers */, CAA20E16288B3E8200EDC764 /* ORKStepView_Private.h in Headers */, CAA20E59288B3E9200EDC764 /* ORKTaskViewController_Private.h in Headers */, + 51FBAC902BD07333009CA28F /* UIImageView+ResearchKit.h in Headers */, CAA20E2C288B3E8200EDC764 /* ORKFormStepViewController_Private.h in Headers */, CAA20D95288B3D9C00EDC764 /* ORKStepContainerView_Private.h in Headers */, CAA20E21288B3E8200EDC764 /* ORKCustomSignatureFooterView_Private.h in Headers */, @@ -4721,7 +4769,6 @@ CAA20E44288B3E8200EDC764 /* ORKTableStepViewController_Internal.h in Headers */, CAA20E35288B3E8200EDC764 /* ORKPasscodeStepViewController_Internal.h in Headers */, CAA20DA3288B3D9C00EDC764 /* ORKNavigationContainerView_Internal.h in Headers */, - CAA20E11288B3E8200EDC764 /* ORKCustomStepView_Internal.h in Headers */, CAA20E18288B3E8200EDC764 /* ORKFormStepViewController_Internal.h in Headers */, CAA20E2D288B3E8200EDC764 /* ORKInstructionStepViewController_Internal.h in Headers */, CAA20D57288B3D6F00EDC764 /* ORKPlaybackButton_Internal.h in Headers */, @@ -4743,7 +4790,6 @@ 511E8D622995C20E00A384A5 /* ORKEnvironmentSPLMeterStepViewController_Private.h in Headers */, CAD08A8C289DE772007B2A98 /* ORKAudioGenerator.h in Headers */, CA2B8F9128A16E3B0025B773 /* ORKEnvironmentSPLMeterContentView.h in Headers */, - CAD08A41289DE617007B2A98 /* HKSample+ORKJSONDictionary.h in Headers */, CA2B8FBB28A175940025B773 /* ORKFitnessContentView.h in Headers */, 5156CA4A2B7E45AE00983535 /* ORKTouchAbilityPinchContentView.h in Headers */, CA2B901028A17BEE0025B773 /* ORKActiveTaskResult.h in Headers */, @@ -4789,6 +4835,7 @@ CAD08A53289DE665007B2A98 /* ORKAudioLevelNavigationRule.h in Headers */, CA2B8FF828A177C10025B773 /* ORKTrailmakingContentView.h in Headers */, 5192BEEE2AE043D3006E43FB /* ORKTimedWalkContentView.h in Headers */, + 51A11F222BD152660060C07E /* ORKActiveStepCustomView.h in Headers */, CAD08A17289DE512007B2A98 /* ORKAmslerGridStep.h in Headers */, CAD08A1B289DE523007B2A98 /* ORKTouchAnywhereStep.h in Headers */, CA2B8FF028A177990025B773 /* ORKToneAudiometryContentView.h in Headers */, @@ -4887,7 +4934,6 @@ CA2B8F6D28A16BAC0025B773 /* ORKSpeechInNoiseContentView.h in Headers */, CAD08A72289DE6E5007B2A98 /* ORKReactionTimeStep.h in Headers */, CAD089ED289DE454007B2A98 /* ORK3DModelManager.h in Headers */, - CAD08A3B289DE5F6007B2A98 /* CMMotionActivity+ORKJSONDictionary.h in Headers */, CAD08A80289DE716007B2A98 /* ORKAccuracyStroopStep.h in Headers */, CAD08A3D289DE609007B2A98 /* ORKHealthClinicalTypeRecorder.h in Headers */, CAD08A76289DE6F3007B2A98 /* ORKSpatialSpanMemoryStep.h in Headers */, @@ -5116,6 +5162,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0B0852742BD872C400149963 /* PrivacyInfo.xcprivacy in Resources */, B1C0F4E41A9BA65F0022C153 /* ResearchKit.strings in Resources */, 5192BFA12AEAD7B5006E43FB /* Artwork.xcassets in Resources */, 714080DB235FD14700281E04 /* ResearchKit.stringsdict in Resources */, @@ -5126,8 +5173,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - CAA20E8C288B3F1100EDC764 /* splMeter_sensitivity_offset.plist in Resources */, - CAA20F1A288B3F4000EDC764 /* SentencesList.txt in Resources */, + 0B0852762BD872D800149963 /* PrivacyInfo.xcprivacy in Resources */, + 0B53DA642BD0595100227126 /* ResearchKitUI.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5135,6 +5182,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5EB91CC92BCE2F1D00BBF23E /* SentencesList.txt in Resources */, + 5EB91CC82BCE2EFD00BBF23E /* splMeter_sensitivity_offset.plist in Resources */, 0BD9B6112B75992800A64EF9 /* Sentence5.wav in Resources */, 51BD8FD329D60FB60001D54E /* volume_curve_AIRPODSMAX.plist in Resources */, 5192BF7F2AE1A9BA006E43FB /* volume_curve_AIRPODSPROV2.plist in Resources */, @@ -5151,6 +5200,7 @@ 51BD8FD729D60FB60001D54E /* frequency_dBSPL_AIRPODSPRO.plist in Resources */, 51AF1B242B69803A00D3B399 /* Noise.wav in Resources */, 5192BF5D2AE19036006E43FB /* frequency_dBSPL_AIRPODSPROV2.plist in Resources */, + 0B0852782BD872EA00149963 /* PrivacyInfo.xcprivacy in Resources */, 51BD8FD029D60FB60001D54E /* volume_curve_AIRPODS.plist in Resources */, 51BD8FD429D60FB60001D54E /* volume_curve_WIRED.plist in Resources */, 0BD9B6132B75992F00A64EF9 /* Sentence7.wav in Resources */, @@ -5191,6 +5241,7 @@ buildActionMask = 2147483647; files = ( 248604061B4C98760010C8A0 /* ORKAnswerFormatTests.m in Sources */, + 5E6AB7DF2BC86900009ED0D5 /* ORKTaskViewControllerTests.swift in Sources */, 86CC8EBA1AC09383001CCD89 /* ORKResultTests.m in Sources */, 03057F492518ECDC00C4EC5B /* ORKAudioStepViewControllerTests.m in Sources */, 0BFD27562B8D1D3B00B540E8 /* ORKJSONSerializationTests.m in Sources */, @@ -5255,7 +5306,6 @@ 861D11AE1AA7951F003C98A7 /* ORKChoiceAnswerFormatHelper.m in Sources */, BF91559D1BDE8D7D007FA459 /* ORKReviewStep.m in Sources */, CA994D5628AB08410019DEA4 /* ORKDeprecated.m in Sources */, - 0B9CC5682A68C02C00080E29 /* UIImageView+ResearchKit.m in Sources */, 00C2668F23022CD400337E0B /* ORKCustomStep.m in Sources */, 866DA5281D63D04700C9AF3F /* ORKMotionActivityQueryOperation.m in Sources */, BCFF24BD1B0798D10044EC35 /* ORKResultPredicate.m in Sources */, @@ -5306,6 +5356,7 @@ 5192BF852AE1BA47006E43FB /* ORKFrontFacingCameraStepResult.m in Sources */, 031A0FC224CF4ECD000E4455 /* ORKSensorPermissionType.m in Sources */, CA6A0D85288B5B370048C1EF /* ORKHTMLPDFPageRenderer.m in Sources */, + 51A11F182BD08D5E0060C07E /* CMMotionActivity+ORKJSONDictionary.m in Sources */, 24A4DA151B8D1115009C797A /* ORKPasscodeStep.m in Sources */, BCA5C0361AEC05F20092AC8D /* ORKStepNavigationRule.m in Sources */, FF919A6A1E81D255005C2A1E /* ORKConsentSignatureResult.m in Sources */, @@ -5327,8 +5378,8 @@ FA7A9D301B083DD3005A2BEA /* ORKConsentSectionFormatter.m in Sources */, FF5CA61C1D2C6453001660A3 /* ORKSignatureStep.m in Sources */, FF919A541E81BEB5005C2A1E /* ORKCollectionResult.m in Sources */, - 5192BFA92AEC4734006E43FB /* (null) in Sources */, 51B94DC72B3254FE0039B0E7 /* CLLocationManager+ResearchKit.m in Sources */, + 51A11F192BD08D5E0060C07E /* HKSample+ORKJSONDictionary.m in Sources */, 86C40D581A8D7C5C00081FAC /* ORKOrderedTask.m in Sources */, 86C40D601A8D7C5C00081FAC /* ORKQuestionStep.m in Sources */, ); @@ -5373,7 +5424,6 @@ CA6A0D82288B54650048C1EF /* ORKConsentReviewController.m in Sources */, CAA20D8A288B3D9100EDC764 /* ORKScaleSliderView.m in Sources */, CAA20F36288B3F6700EDC764 /* ORKLoginStepViewController.m in Sources */, - CAA20EEA288B3F1200EDC764 /* ORKActiveStepQuantityView.m in Sources */, CAA20D4F288B3D5700EDC764 /* ORKRecordButton.m in Sources */, CAA20DE0288B3DB400EDC764 /* ORKCountdownLabel.m in Sources */, CAA20D7F288B3D9100EDC764 /* SwiftUIViewFactory.swift in Sources */, @@ -5423,7 +5473,6 @@ CAA20F2E288B3F5B00EDC764 /* ORKConsentReviewStepViewController.m in Sources */, 51F716D3297E2FB600D8ACF7 /* ORKConsentLearnMoreViewController.m in Sources */, CAA20D90288B3D9100EDC764 /* ORKTextChoiceCellGroup.m in Sources */, - CAA20E7C288B3F1100EDC764 /* ORKActiveStepView.m in Sources */, CAA20D51288B3D6400EDC764 /* ORKCheckmarkView.m in Sources */, CAA20E20288B3E8200EDC764 /* ORKSignatureStepViewController.m in Sources */, CAA20DE2288B3DB400EDC764 /* ORKRoundTappingButton.m in Sources */, @@ -5457,6 +5506,7 @@ CAA20F3A288B3F6D00EDC764 /* ORKAccessibilityFunctions.m in Sources */, 5192BF982AE1C5A1006E43FB /* ORKAnswerFormat+FormStepViewControllerAdditions.m in Sources */, CAA20E01288B3E8100EDC764 /* ORKRequestPermissionsStepContainerView.m in Sources */, + 51A11F242BD1548C0060C07E /* UIImageView+ResearchKit.m in Sources */, CAA20F38288B3F6700EDC764 /* ORKVerificationStepView.m in Sources */, CAA20D6C288B3D9100EDC764 /* ORKSurveyAnswerCellForScale.m in Sources */, CAA20E2A288B3E8200EDC764 /* ORKStepView.m in Sources */, @@ -5479,6 +5529,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5EB91CC72BCE2EE600BBF23E /* ORKActiveStepView.m in Sources */, + 5EB91CC62BCE2ED500BBF23E /* ORKActiveStepQuantityView.m in Sources */, CAD08A7F289DE714007B2A98 /* ORKStroopStep.m in Sources */, CAD08A34289DE5DB007B2A98 /* ORKStreamingAudioRecorder.m in Sources */, 5156C9C82B7E426900983535 /* ORKTouchAbilityArrowView.m in Sources */, @@ -5486,7 +5538,6 @@ 5156CA322B7E451C00983535 /* ORKTouchAbilityScrollResult.m in Sources */, CAD08A1A289DE51D007B2A98 /* ORKAmslerGridResult.m in Sources */, CA2B8FAA28A175360025B773 /* ORKAudioStepViewController.m in Sources */, - CAD08A3C289DE5F9007B2A98 /* CMMotionActivity+ORKJSONDictionary.m in Sources */, CA2B8FF628A177BF0025B773 /* ORKTrailmakingStepViewController.m in Sources */, CA2B8FF728A177BF0025B773 /* ORKTrailmakingContentView.m in Sources */, CAD08A75289DE6F1007B2A98 /* ORKSpatialSpanMemoryResult.m in Sources */, @@ -5503,6 +5554,7 @@ CA2B8F8C28A16E2E0025B773 /* ORKEnvironmentSPLMeterBarView.m in Sources */, CAD08A9D289DE7B5007B2A98 /* ORKWalkingTaskStep.m in Sources */, CAD08A0E289DE4E2007B2A98 /* ORKAudiometry.m in Sources */, + 51A11F232BD152660060C07E /* ORKActiveStepCustomView.m in Sources */, CA2B8FD128A176B40025B773 /* ORKRangeOfMotionStepViewController.m in Sources */, CA2B8F8228A16CF40025B773 /* ORK3DModelStepViewController.m in Sources */, 5156CA612B7E465500983535 /* ORKTouchAbilityRotationTrial.m in Sources */, @@ -5567,7 +5619,6 @@ CAD08A4C289DE63F007B2A98 /* ORKTouchRecorder.m in Sources */, CAD08A18289DE516007B2A98 /* ORKAmslerGridStep.m in Sources */, 5156CA2E2B7E451C00983535 /* ORKTouchAbilityScrollStep.m in Sources */, - CAD08A42289DE61A007B2A98 /* HKSample+ORKJSONDictionary.m in Sources */, CAD08A4E289DE644007B2A98 /* UITouch+ORKJSONDictionary.m in Sources */, 5156C9D82B7E42C200983535 /* ORKTouchAbilityGestureRecoginzerEvent.m in Sources */, CAD08A71289DE6E2007B2A98 /* ORKReactionTimeResult.m in Sources */, @@ -5699,6 +5750,14 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ + 0B53DA622BD0595100227126 /* ResearchKitUI.strings */ = { + isa = PBXVariantGroup; + children = ( + 0B53DA632BD0595100227126 /* en */, + ); + name = ResearchKitUI.strings; + sourceTree = ""; + }; 714080D9235FD14700281E04 /* ResearchKit.stringsdict */ = { isa = PBXVariantGroup; children = ( @@ -5812,6 +5871,7 @@ "$(ORK_GCC_PREPROCESSOR_DEFINITIONS)", ); IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MODULEMAP_PRIVATE_FILE = ResearchKit/ResearchKit_Private.modulemap; "OTHER_SWIFT_FLAGS[arch=*]" = "$(inherited) -runtime-compatibility-version none"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; @@ -5824,6 +5884,7 @@ baseConfigurationReference = 5D000EC62620F27100E5442A /* ResearchKit-Release.xcconfig */; buildSettings = { IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MODULEMAP_PRIVATE_FILE = ResearchKit/ResearchKit_Private.modulemap; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; TARGETED_DEVICE_FAMILY = "1,2"; @@ -5835,8 +5896,10 @@ baseConfigurationReference = CA481E8228CBD79B001C4D49 /* ResearchKitUI-iOS-Debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; + CURRENT_PROJECT_VERSION = ""; ENABLE_MODULE_VERIFIER = YES; ENABLE_TESTING_SEARCH_PATHS = YES; + MODULEMAP_PRIVATE_FILE = ResearchKitUI/ResearchKitUI_Private.modulemap; PRODUCT_NAME = ResearchKitUI; SUPPORTS_MACCATALYST = NO; SWIFT_OBJC_BRIDGING_HEADER = ""; @@ -5849,8 +5912,10 @@ baseConfigurationReference = CA481E8428CBD835001C4D49 /* ResearchKitUI-iOS-Release.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; + CURRENT_PROJECT_VERSION = ""; ENABLE_MODULE_VERIFIER = YES; ENABLE_TESTING_SEARCH_PATHS = YES; + MODULEMAP_PRIVATE_FILE = ResearchKitUI/ResearchKitUI_Private.modulemap; PRODUCT_NAME = ResearchKitUI; SUPPORTS_MACCATALYST = NO; SWIFT_OBJC_BRIDGING_HEADER = ""; @@ -5892,7 +5957,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = NO; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -5908,7 +5973,8 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - GENERATE_INFOPLIST_FILE = YES; + GENERATE_INFOPLIST_FILE = NO; + INFOPLIST_FILE = ResearchKitActiveTask/Info.plist; INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 researchkit.org. All rights reserved."; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( @@ -5917,6 +5983,7 @@ "@loader_path/Frameworks", ); MARKETING_VERSION = 1.0; + MODULEMAP_PRIVATE_FILE = ResearchKitActiveTask/ResearchKitActiveTask_Private.modulemap; "OTHER_SWIFT_FLAGS[arch=*]" = ""; PRODUCT_BUNDLE_IDENTIFIER = org.researchkit.ResearchKitActiveTask; SKIP_INSTALL = YES; @@ -5962,7 +6029,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = NO; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -5977,7 +6044,8 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - GENERATE_INFOPLIST_FILE = YES; + GENERATE_INFOPLIST_FILE = NO; + INFOPLIST_FILE = ResearchKitActiveTask/Info.plist; INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 researchkit.org. All rights reserved."; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( @@ -5986,6 +6054,7 @@ "@loader_path/Frameworks", ); MARKETING_VERSION = 1.0; + MODULEMAP_PRIVATE_FILE = ResearchKitActiveTask/ResearchKitActiveTask_Private.modulemap; PRODUCT_BUNDLE_IDENTIFIER = org.researchkit.ResearchKitActiveTask; SKIP_INSTALL = YES; SUPPORTS_MACCATALYST = NO; diff --git a/ResearchKit.xcodeproj/xcshareddata/xcschemes/ResearchKitTests.xcscheme b/ResearchKit.xcodeproj/xcshareddata/xcschemes/ResearchKitTests.xcscheme index 69a9b6de93..f267b0c018 100644 --- a/ResearchKit.xcodeproj/xcshareddata/xcschemes/ResearchKitTests.xcscheme +++ b/ResearchKit.xcodeproj/xcshareddata/xcschemes/ResearchKitTests.xcscheme @@ -33,7 +33,7 @@ diff --git a/ResearchKitActiveTask/Common/Recorders/Device Motion/CMMotionActivity+ORKJSONDictionary.h b/ResearchKit/Common/CMMotionActivity+ORKJSONDictionary.h similarity index 98% rename from ResearchKitActiveTask/Common/Recorders/Device Motion/CMMotionActivity+ORKJSONDictionary.h rename to ResearchKit/Common/CMMotionActivity+ORKJSONDictionary.h index 8c599f3199..e9ddddc9c6 100644 --- a/ResearchKitActiveTask/Common/Recorders/Device Motion/CMMotionActivity+ORKJSONDictionary.h +++ b/ResearchKit/Common/CMMotionActivity+ORKJSONDictionary.h @@ -29,7 +29,7 @@ */ -@import CoreMotion; +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Common/Recorders/Device Motion/CMMotionActivity+ORKJSONDictionary.m b/ResearchKit/Common/CMMotionActivity+ORKJSONDictionary.m similarity index 100% rename from ResearchKitActiveTask/Common/Recorders/Device Motion/CMMotionActivity+ORKJSONDictionary.m rename to ResearchKit/Common/CMMotionActivity+ORKJSONDictionary.m diff --git a/ResearchKitActiveTask/Common/Recorders/Health/HKSample+ORKJSONDictionary.h b/ResearchKit/Common/HKSample+ORKJSONDictionary.h similarity index 98% rename from ResearchKitActiveTask/Common/Recorders/Health/HKSample+ORKJSONDictionary.h rename to ResearchKit/Common/HKSample+ORKJSONDictionary.h index 3cb4f06279..3008a62f12 100644 --- a/ResearchKitActiveTask/Common/Recorders/Health/HKSample+ORKJSONDictionary.h +++ b/ResearchKit/Common/HKSample+ORKJSONDictionary.h @@ -29,8 +29,7 @@ */ -@import HealthKit; - +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Common/Recorders/Health/HKSample+ORKJSONDictionary.m b/ResearchKit/Common/HKSample+ORKJSONDictionary.m similarity index 100% rename from ResearchKitActiveTask/Common/Recorders/Health/HKSample+ORKJSONDictionary.m rename to ResearchKit/Common/HKSample+ORKJSONDictionary.m diff --git a/ResearchKit/Common/ORKAnswerFormat_Internal.h b/ResearchKit/Common/ORKAnswerFormat_Internal.h index 92256613b3..83f31cad6f 100644 --- a/ResearchKit/Common/ORKAnswerFormat_Internal.h +++ b/ResearchKit/Common/ORKAnswerFormat_Internal.h @@ -29,7 +29,7 @@ */ -@import HealthKit; +#import #if TARGET_OS_IOS #import #import diff --git a/ResearchKit/Common/ORKBodyItem.h b/ResearchKit/Common/ORKBodyItem.h index 8c6d65b22a..8fbe7401c0 100644 --- a/ResearchKit/Common/ORKBodyItem.h +++ b/ResearchKit/Common/ORKBodyItem.h @@ -79,6 +79,8 @@ ORK_CLASS_AVAILABLE - (instancetype)initWithText:(nullable NSString *)text detailText:(nullable NSString *)detailText image:(nullable UIImage *)image learnMoreItem:(nullable ORKLearnMoreItem *)learnMoreItem bodyItemStyle:(ORKBodyItemStyle)bodyItemStyle useCardStyle:(BOOL)useCardStyle; +- (instancetype)initWithText:(nullable NSString *)text detailText:(nullable NSString *)detailText image:(nullable UIImage *)image learnMoreItem:(nullable ORKLearnMoreItem *)learnMoreItem bodyItemStyle:(ORKBodyItemStyle)bodyItemStyle useCardStyle:(BOOL)useCardStyle alignImageToTop:(BOOL)alignImageToTop; + - (instancetype)initWithHorizontalRule; @property (nonatomic, nullable) NSString *text; @@ -95,6 +97,8 @@ ORK_CLASS_AVAILABLE @property (nonatomic) BOOL useSecondaryColor; +@property (nonatomic) BOOL alignImageToTop; + @end NS_ASSUME_NONNULL_END diff --git a/ResearchKit/Common/ORKBodyItem.m b/ResearchKit/Common/ORKBodyItem.m index 93f5860e1b..14244d010b 100644 --- a/ResearchKit/Common/ORKBodyItem.m +++ b/ResearchKit/Common/ORKBodyItem.m @@ -61,6 +61,10 @@ - (instancetype)initWithText:(NSString *)text detailText:(NSString *)detailText } - (instancetype)initWithText:(NSString *)text detailText:(NSString *)detailText image:(nullable UIImage *)image learnMoreItem:(nullable ORKLearnMoreItem *)learnMoreItem bodyItemStyle:(ORKBodyItemStyle)bodyItemStyle useCardStyle:(BOOL)useCardStyle { + return [self initWithText:text detailText:detailText image:image learnMoreItem:learnMoreItem bodyItemStyle:bodyItemStyle useCardStyle:NO alignImageToTop:false]; +} + +- (instancetype)initWithText:(NSString *)text detailText:(NSString *)detailText image:(nullable UIImage *)image learnMoreItem:(nullable ORKLearnMoreItem *)learnMoreItem bodyItemStyle:(ORKBodyItemStyle)bodyItemStyle useCardStyle:(BOOL)useCardStyle alignImageToTop:(BOOL)alignImageToTop { self = [super init]; if (self) { self.text = text; @@ -70,6 +74,7 @@ - (instancetype)initWithText:(NSString *)text detailText:(NSString *)detailText self.image = image; self.useCardStyle = useCardStyle; self.useSecondaryColor = NO; + self.alignImageToTop = alignImageToTop; } [self validateParameters]; return self; @@ -127,6 +132,7 @@ - (nonnull id)copyWithZone:(nullable NSZone *)zone { bodyItem->_image = [self.image copy]; bodyItem->_useCardStyle = self.useCardStyle; bodyItem->_useSecondaryColor = self.useSecondaryColor; + bodyItem->_alignImageToTop = self.alignImageToTop; return bodyItem; } @@ -146,7 +152,8 @@ - (BOOL)isEqual:(id)object { && (self.bodyItemStyle == castObject.bodyItemStyle) && ORKEqualObjects(self.image, castObject.image) && (self.useCardStyle == castObject.useCardStyle) - && (self.useSecondaryColor == castObject.useSecondaryColor)); + && (self.useSecondaryColor == castObject.useSecondaryColor) + && (self.alignImageToTop == castObject.alignImageToTop)); } @end diff --git a/ResearchKit/Common/ORKChoiceAnswerFormatHelper.h b/ResearchKit/Common/ORKChoiceAnswerFormatHelper.h index 434ccd33ef..8ab7ff1eb2 100644 --- a/ResearchKit/Common/ORKChoiceAnswerFormatHelper.h +++ b/ResearchKit/Common/ORKChoiceAnswerFormatHelper.h @@ -28,7 +28,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -@import Foundation; +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKit/Common/ORKDataLogger.h b/ResearchKit/Common/ORKDataLogger.h index 09d4992f90..9dc21f88bc 100644 --- a/ResearchKit/Common/ORKDataLogger.h +++ b/ResearchKit/Common/ORKDataLogger.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import diff --git a/ResearchKit/Common/ORKDataLogger.m b/ResearchKit/Common/ORKDataLogger.m index 3b02c5a319..558554985c 100644 --- a/ResearchKit/Common/ORKDataLogger.m +++ b/ResearchKit/Common/ORKDataLogger.m @@ -32,9 +32,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKDataLogger.h" #import "ORKHelpers_Internal.h" -#import "CMMotionActivity+ORKJSONDictionary.h" -#import "HKSample+ORKJSONDictionary.h" - #include diff --git a/ResearchKit/Common/ORKErrors.h b/ResearchKit/Common/ORKErrors.h index 2aec16df57..3244068f00 100644 --- a/ResearchKit/Common/ORKErrors.h +++ b/ResearchKit/Common/ORKErrors.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #if TARGET_OS_IOS #import diff --git a/ResearchKit/Common/ORKFormStep.h b/ResearchKit/Common/ORKFormStep.h index ddcda1d5a1..2047cb4f4e 100644 --- a/ResearchKit/Common/ORKFormStep.h +++ b/ResearchKit/Common/ORKFormStep.h @@ -111,6 +111,14 @@ ORK_CLASS_AVAILABLE @property (nonatomic) ORKCardViewStyle cardViewStyle; +/** + A boolean to determine if the form will auto scroll when a + answer is selected. + + The default value is YES. + */ +@property (nonatomic) BOOL autoScrollEnabled; + @end diff --git a/ResearchKit/Common/ORKFormStep.m b/ResearchKit/Common/ORKFormStep.m index dd653219a5..0a9be8541b 100644 --- a/ResearchKit/Common/ORKFormStep.m +++ b/ResearchKit/Common/ORKFormStep.m @@ -53,6 +53,7 @@ - (instancetype)initWithIdentifier:(NSString *)identifier self.optional = YES; self.useSurveyMode = YES; self.useCardView = YES; + self.autoScrollEnabled = YES; self.cardViewStyle = ORKCardViewStyleDefault; } return self; @@ -64,6 +65,7 @@ - (instancetype)initWithIdentifier:(NSString *)identifier { self.optional = YES; self.useSurveyMode = YES; self.useCardView = YES; + self.autoScrollEnabled = YES; self.cardViewStyle = ORKCardViewStyleDefault; } return self; @@ -93,6 +95,7 @@ - (instancetype)copyWithZone:(NSZone *)zone { ORKFormStep *step = [super copyWithZone:zone]; step.formItems = ORKArrayCopyObjects(_formItems); step.cardViewStyle = self.cardViewStyle; + step.autoScrollEnabled = self.autoScrollEnabled; return step; } @@ -102,7 +105,8 @@ - (BOOL)isEqual:(id)object { __typeof(self) castObject = object; return (isParentSame && (ORKEqualObjects(self.formItems, castObject.formItems)) && - self.cardViewStyle == castObject.cardViewStyle); + self.cardViewStyle == castObject.cardViewStyle && + self.autoScrollEnabled == castObject.autoScrollEnabled); } - (NSUInteger)hash { @@ -145,6 +149,7 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder { if (self) { ORK_DECODE_OBJ_ARRAY(aDecoder, formItems, ORKFormItem); ORK_DECODE_BOOL(aDecoder, useCardView); + ORK_DECODE_BOOL(aDecoder, autoScrollEnabled); ORK_DECODE_OBJ_CLASS(aDecoder, footerText, NSString); ORK_DECODE_ENUM(aDecoder, cardViewStyle); } @@ -155,6 +160,7 @@ - (void)encodeWithCoder:(NSCoder *)aCoder { [super encodeWithCoder:aCoder]; ORK_ENCODE_OBJ(aCoder, formItems); ORK_ENCODE_BOOL(aCoder, useCardView); + ORK_ENCODE_BOOL(aCoder, autoScrollEnabled); ORK_ENCODE_OBJ(aCoder, footerText); ORK_ENCODE_ENUM(aCoder, cardViewStyle); } diff --git a/ResearchKit/Common/ORKHelpers.m b/ResearchKit/Common/ORKHelpers.m index 0cb5535ae5..1fda3e8cb9 100644 --- a/ResearchKit/Common/ORKHelpers.m +++ b/ResearchKit/Common/ORKHelpers.m @@ -559,3 +559,4 @@ void ORKAdjustPageViewControllerNavigationDirectionForRTL(UIPageViewControllerNa numberFormatter.usesGroupingSeparator = NO; return numberFormatter; } + diff --git a/ResearchKit/Common/ORKHelpers_Internal.h b/ResearchKit/Common/ORKHelpers_Internal.h index 89d3d9384c..15a5e3b17d 100644 --- a/ResearchKit/Common/ORKHelpers_Internal.h +++ b/ResearchKit/Common/ORKHelpers_Internal.h @@ -30,7 +30,7 @@ */ -@import UIKit; +#import #if TARGET_OS_IOS #import @@ -211,6 +211,7 @@ UIFontDescriptor *ORKFontDescriptorForLightStylisticAlternative(UIFontDescriptor CGFloat ORKFloorToViewScale(CGFloat value, UIView *view); #endif + ORK_INLINE bool ORKEqualObjects(id o1, id o2) { return (o1 == o2) || (o1 && o2 && [o1 isEqual:o2]); diff --git a/ResearchKit/Common/ORKHelpers_Private.h b/ResearchKit/Common/ORKHelpers_Private.h index 71ba5f5b60..c021bfd702 100644 --- a/ResearchKit/Common/ORKHelpers_Private.h +++ b/ResearchKit/Common/ORKHelpers_Private.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #if TARGET_OS_IOS #import #endif diff --git a/ResearchKit/Common/ORKQuestionResult_Private.h b/ResearchKit/Common/ORKQuestionResult_Private.h index 659dcdf829..ddc3d35383 100644 --- a/ResearchKit/Common/ORKQuestionResult_Private.h +++ b/ResearchKit/Common/ORKQuestionResult_Private.h @@ -34,7 +34,7 @@ #import #endif -@import MapKit; +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKit/Common/ORKRecorder.h b/ResearchKit/Common/ORKRecorder.h index ad3c805f8b..3b0b962ef7 100644 --- a/ResearchKit/Common/ORKRecorder.h +++ b/ResearchKit/Common/ORKRecorder.h @@ -335,98 +335,6 @@ ORK_CLASS_AVAILABLE @end -/** - A configuration object that records data from a HealthKit quantity type during an active step. - - Before you can use this configuration, you must use Xcode to enable the appropriate HealthKit entitlement - for your app. - - HealthKit quantity type data is serialized to JSON and returned as an `ORKFileResult` object. - For details on the format, see `HKSample+ORKJSONDictionary`. - - To use a recorder, include its configuration in the `recorderConfigurations` property - of an `ORKActiveStep` object, include that step in a task, and present it with - a task view controller. - */ -ORK_CLASS_AVAILABLE -@interface ORKHealthQuantityTypeRecorderConfiguration : ORKRecorderConfiguration - -/** - Returns an initialized health quantity type recorder configuration using the specified quantity type and unit designation. - - This method is the designated initializer. - - @param identifier The unique identifier of the recorder configuration. - @param quantityType The quantity type that should be collected during the active task. - @param unit The unit for the data that should be collected and serialized. - - @return An initialized health quantity type recorder configuration. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier healthQuantityType:(HKQuantityType *)quantityType unit:(HKUnit *)unit NS_DESIGNATED_INITIALIZER; - -/** - Returns a new health quantity type recorder configuration initialized from data in the given unarchiver. - - @param aDecoder Coder from which to initialize the health quantity type recorder configuration. - - @return A new health quantity type recorder configuration. - */ -- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER; - -/** - The quantity type to be collected from HealthKit. (read-only) - */ -@property (nonatomic, readonly, copy) HKQuantityType *quantityType; - -/** - The unit in which to serialize the data from HealthKit. (read-only) - */ -@property (nonatomic, readonly, copy) HKUnit *unit; - -@end - -ORK_CLASS_AVAILABLE -#if defined(__IPHONE_12_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_12_0 -API_AVAILABLE(ios(12.0)) -@interface ORKHealthClinicalTypeRecorderConfiguration : ORKRecorderConfiguration - -/** - Returns an initialized health clinical type recorder configuration using the specified clinical type. - - This method is the designated initializer. - - @param identifier The unique identifier of the recorder configuration. - @param healthClinicalType The HKClinicalType that should be collected during the active task. - @param healthFHIRResourceType The HKFHIRResourceType that should be used as predicate while querying for the healthClinicalType. Providing a HKFHIRResourceType that does not correspond to a HKClinicalType will NOT generate any result. - - @return An initialized health clinical type recorder configuration. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier - healthClinicalType:(HKClinicalType *)healthClinicalType - healthFHIRResourceType:(nullable HKFHIRResourceType)healthFHIRResourceType NS_DESIGNATED_INITIALIZER API_AVAILABLE(ios(12.0)); - -/** - Returns a new health clinical type recorder configuration initialized from data in the given unarchiver. - - @param aDecoder Coder from which to initialize the health clinical type recorder configuration. - - @return A new health clinical type recorder configuration. - */ -- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER; - -/** - The HKClinicalType to be collected from HealthKit. (read-only) - */ -@property (nonatomic, readonly, copy) HKClinicalType *healthClinicalType; - -/** - The HKFHIRResourceType to used as predicate for HKQuery. (read-only) - */ -@property (nonatomic, readonly, copy) HKFHIRResourceType healthFHIRResourceType; - -@end -#endif - /** A configuration object that records streaming audio data during an active step. diff --git a/ResearchKit/Common/ORKRecorder_Private.h b/ResearchKit/Common/ORKRecorder_Private.h index 9ee25a5926..e2d7cf1e33 100644 --- a/ResearchKit/Common/ORKRecorder_Private.h +++ b/ResearchKit/Common/ORKRecorder_Private.h @@ -37,38 +37,6 @@ NS_ASSUME_NONNULL_BEGIN @class ORKStep; -/** - The `ORKTouchRecorderConfiguration` is a recorder configuration class for - generating an `ORKTouchRecorder`. - - It is currently considered private, and is not used in any of the active tasks. - */ -ORK_CLASS_AVAILABLE -@interface ORKTouchRecorderConfiguration : ORKRecorderConfiguration - -/** - Returns an initialized touch recorder configuration. - - This method is the designated initializer. - - @param identifier The unique identifier of the recorder configuration. - - @return An initialized touch recorder configuration. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier NS_DESIGNATED_INITIALIZER; - -/** - Returns a new touch recorder configuration initialized from data in the given unarchiver. - - @param aDecoder Coder from which to initialize the touch recorder configuration. - - @return A new touch recorder configuration. - */ -- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER; - -@end - - @interface ORKRecorder () /** diff --git a/ResearchKit/Common/ORKSkin_Private.h b/ResearchKit/Common/ORKSkin_Private.h index 0e7d087be0..9717032d36 100644 --- a/ResearchKit/Common/ORKSkin_Private.h +++ b/ResearchKit/Common/ORKSkin_Private.h @@ -29,7 +29,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -@import UIKit; +#import #if TARGET_OS_IOS #import diff --git a/ResearchKit/Common/ORKTypes_Private.h b/ResearchKit/Common/ORKTypes_Private.h index f93d71647b..9c40ce448b 100644 --- a/ResearchKit/Common/ORKTypes_Private.h +++ b/ResearchKit/Common/ORKTypes_Private.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import #import #import diff --git a/ResearchKit/Configuration/ResearchKitActiveTask/ResearchKitActiveTask-Shared.xcconfig b/ResearchKit/Configuration/ResearchKitActiveTask/ResearchKitActiveTask-Shared.xcconfig index 71bd4bdf00..b68031c5dc 100644 --- a/ResearchKit/Configuration/ResearchKitActiveTask/ResearchKitActiveTask-Shared.xcconfig +++ b/ResearchKit/Configuration/ResearchKitActiveTask/ResearchKitActiveTask-Shared.xcconfig @@ -5,6 +5,6 @@ #include "../ResearchKit/ResearchKit-Shared.xcconfig" GCC_PREFIX_HEADER = -INFOPLIST_FILE = +INFOPLIST_FILE = ResearchKitActiveTask/Info.plist MODULEMAP_FILE = ResearchKitActiveTask/ResearchKitActiveTask.modulemap PRODUCT_NAME = ResearchKitActiveTask diff --git a/ResearchKit/PrivacyInfo.xcprivacy b/ResearchKit/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..f274381337 --- /dev/null +++ b/ResearchKit/PrivacyInfo.xcprivacy @@ -0,0 +1,72 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypePhotosorVideos + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeSensitiveInfo + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeHealth + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypePreciseLocation + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + + diff --git a/ResearchKit/ResearchKit.h b/ResearchKit/ResearchKit.h index ee2cd051ab..03fe91244b 100644 --- a/ResearchKit/ResearchKit.h +++ b/ResearchKit/ResearchKit.h @@ -111,3 +111,6 @@ #import #import #import + +#import +#import diff --git a/ResearchKit/ResearchKit.modulemap b/ResearchKit/ResearchKit.modulemap index 7e39c58517..6509a07dec 100644 --- a/ResearchKit/ResearchKit.modulemap +++ b/ResearchKit/ResearchKit.modulemap @@ -6,10 +6,3 @@ framework module ResearchKit { export * } } - -framework module ResearchKit_Private { - umbrella header "ResearchKit_Private.h" - - export * - module * { export * } -} diff --git a/ResearchKit/ResearchKit_Private.modulemap b/ResearchKit/ResearchKit_Private.modulemap new file mode 100644 index 0000000000..29860eee5e --- /dev/null +++ b/ResearchKit/ResearchKit_Private.modulemap @@ -0,0 +1,36 @@ +/* + Copyright (c) 2024, 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. + */ + +framework module ResearchKit_Private { + umbrella header "ResearchKit_Private.h" + + export * + module * { export * } +} diff --git a/ResearchKit/Stale/ORKConsentDocument.m b/ResearchKit/Stale/ORKConsentDocument.m index 3c6e4b2401..1ccbbf61d0 100644 --- a/ResearchKit/Stale/ORKConsentDocument.m +++ b/ResearchKit/Stale/ORKConsentDocument.m @@ -43,6 +43,8 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKErrors.h" #import "ORKSkin_Private.h" +static NSString *const _ORKSignaturesKey = @"signatures"; + @implementation ORKConsentDocument { NSMutableArray *_signatures; } @@ -233,8 +235,7 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder { ORK_DECODE_OBJ_CLASS(aDecoder, signaturePageTitle, NSString); ORK_DECODE_OBJ_CLASS(aDecoder, signaturePageContent, NSString); ORK_DECODE_OBJ_CLASS(aDecoder, htmlReviewContent, NSString); - NSArray *signatures = (NSArray *)[aDecoder decodeObjectOfClass:[NSArray class] forKey:@"signatures"]; - _signatures = [signatures mutableCopy]; + _signatures = [aDecoder decodeObjectOfClasses:[NSSet setWithArray:@[NSMutableArray.self, ORKConsentSignature.self]] forKey:_ORKSignaturesKey]; ORK_DECODE_OBJ_ARRAY(aDecoder, sections, ORKConsentSection); } return self; diff --git a/ResearchKit/Stale/ORKQuestionStep.h b/ResearchKit/Stale/ORKQuestionStep.h index bd635379fe..5f9ff9415f 100644 --- a/ResearchKit/Stale/ORKQuestionStep.h +++ b/ResearchKit/Stale/ORKQuestionStep.h @@ -77,6 +77,7 @@ ORK_CLASS_AVAILABLE question:(nullable NSString *)question answer:(nullable ORKAnswerFormat *)answerFormat; +#if TARGET_OS_IOS /** Returns a new question step that includes the specified identifier, title, question, and answer format. @@ -101,6 +102,7 @@ ORK_CLASS_AVAILABLE answer:(nullable ORKAnswerFormat *)answerFormat learnMoreItem:(nullable ORKLearnMoreItem *)learnMoreItem useCardView:(nullable NSNumber *)useCardView; +#endif /** The format of the answer. diff --git a/ResearchKit/Stale/ORKQuestionStep_Private.h b/ResearchKit/Stale/ORKQuestionStep_Private.h index 35551bddff..37ae14b731 100644 --- a/ResearchKit/Stale/ORKQuestionStep_Private.h +++ b/ResearchKit/Stale/ORKQuestionStep_Private.h @@ -48,12 +48,15 @@ ORK_EXTERN ORKQuestionStepPresentationStyle const ORKQuestionStepPresentationSty @protocol ORKQuestionStepPresentation +#if TARGET_OS_IOS @property (nonatomic, copy) ORKQuestionStepPresentationStyle presentationStyle; +#endif @end @interface ORKQuestionStep () +#if TARGET_OS_IOS /** Platter presentation style initializer. Since this uses a custom layout for step details, this is the recommended way use the ORKQuestionStepPresentationStylePlatter. @@ -67,10 +70,12 @@ ORK_EXTERN ORKQuestionStepPresentationStyle const ORKQuestionStepPresentationSty Using configurations other than what is specified above will cause a runtime exception. */ + + (instancetype)platterQuestionWithIdentifier:(NSString *)identifier question:(NSString *)question text:(NSString *)text answerFormat:(ORKAnswerFormat *)answerFormat; +#endif @end diff --git a/ResearchKitActiveTask/3D Model/ORK3DModelStepContentView.h b/ResearchKitActiveTask/3D Model/ORK3DModelStepContentView.h index 58d1cddd2e..1701a76911 100644 --- a/ResearchKitActiveTask/3D Model/ORK3DModelStepContentView.h +++ b/ResearchKitActiveTask/3D Model/ORK3DModelStepContentView.h @@ -31,7 +31,7 @@ @import UIKit; #import "ORK3DModelStep.h" -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/3D Model/ORK3DModelStepViewController.m b/ResearchKitActiveTask/3D Model/ORK3DModelStepViewController.m index 4a4b1ad7ed..5b111b0340 100644 --- a/ResearchKitActiveTask/3D Model/ORK3DModelStepViewController.m +++ b/ResearchKitActiveTask/3D Model/ORK3DModelStepViewController.m @@ -35,7 +35,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORK3DModelStepViewController.h" #import "ORKActiveStepView.h" #import "ORKActiveStepViewController_Internal.h" -#import "ORKBorderedButton.h" #import "ORKCollectionResult_Private.h" #import "ORKHelpers_Internal.h" #import "ORKNavigationContainerView_Internal.h" diff --git a/ResearchKitActiveTask/AmslerGrid/ORKAmslerGridContentView.h b/ResearchKitActiveTask/AmslerGrid/ORKAmslerGridContentView.h index 73ac9aae7d..63f62905a4 100644 --- a/ResearchKitActiveTask/AmslerGrid/ORKAmslerGridContentView.h +++ b/ResearchKitActiveTask/AmslerGrid/ORKAmslerGridContentView.h @@ -29,7 +29,8 @@ */ #import -#import "ORKCustomStepView_Internal.h" + +#import "ORKActiveStepCustomView.h" NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/AmslerGrid/ORKAmslerGridStepViewController.m b/ResearchKitActiveTask/AmslerGrid/ORKAmslerGridStepViewController.m index f16cba5157..9ddcee9314 100644 --- a/ResearchKitActiveTask/AmslerGrid/ORKAmslerGridStepViewController.m +++ b/ResearchKitActiveTask/AmslerGrid/ORKAmslerGridStepViewController.m @@ -43,7 +43,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKAmslerGridResult.h" #import "ORKResult_Private.h" #import "ORKCollectionResult_Private.h" -#import "ORKBorderedButton.h" @interface ORKAmslerGridStepViewController () { diff --git a/ResearchKitActiveTask/Audio/ORKAudioContentView.h b/ResearchKitActiveTask/Audio/ORKAudioContentView.h index aa4f1f02d9..ec9f0683b4 100644 --- a/ResearchKitActiveTask/Audio/ORKAudioContentView.h +++ b/ResearchKitActiveTask/Audio/ORKAudioContentView.h @@ -30,7 +30,8 @@ @import UIKit; -#import "ORKCustomStepView_Internal.h" + +#import "ORKActiveStepCustomView.h" NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Audio/ORKAudioMeteringView.h b/ResearchKitActiveTask/Audio/ORKAudioMeteringView.h index 38223eaf47..432d22611a 100644 --- a/ResearchKitActiveTask/Audio/ORKAudioMeteringView.h +++ b/ResearchKitActiveTask/Audio/ORKAudioMeteringView.h @@ -30,7 +30,7 @@ -@import UIKit; +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Audio/ORKAudioStep.h b/ResearchKitActiveTask/Audio/ORKAudioStep.h index fe114dba0b..e44c6f2566 100644 --- a/ResearchKitActiveTask/Audio/ORKAudioStep.h +++ b/ResearchKitActiveTask/Audio/ORKAudioStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import diff --git a/ResearchKitActiveTask/Audio/ORKAudioStepViewController.m b/ResearchKitActiveTask/Audio/ORKAudioStepViewController.m index 476b1028e9..1fdc28d78b 100644 --- a/ResearchKitActiveTask/Audio/ORKAudioStepViewController.m +++ b/ResearchKitActiveTask/Audio/ORKAudioStepViewController.m @@ -34,7 +34,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKActiveStepTimer.h" #import "ORKActiveStepView.h" #import "ORKAudioContentView.h" -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" #import "ORKVerticalContainerView.h" #import "ORKActiveStepViewController_Internal.h" diff --git a/ResearchKitActiveTask/Common/Active Step/ORKActiveStepViewController.m b/ResearchKitActiveTask/Common/Active Step/ORKActiveStepViewController.m index 8877a88b74..cbd3e447a3 100644 --- a/ResearchKitActiveTask/Common/Active Step/ORKActiveStepViewController.m +++ b/ResearchKitActiveTask/Common/Active Step/ORKActiveStepViewController.m @@ -133,6 +133,10 @@ - (void)setActiveStepView { [self.view addSubview:_activeStepView]; } +- (void)setNavigationFooterViewHidden:(BOOL)hidden { + [_navigationFooterView setHidden:hidden]; +} + - (void)setNavigationFooterView { if (!_navigationFooterView) { _navigationFooterView = _activeStepView.navigationFooterView; @@ -573,7 +577,7 @@ - (void)decodeRestorableStateWithCoder:(NSCoder *)coder { [super decodeRestorableStateWithCoder:coder]; self.finished = [coder decodeBoolForKey:_ORKFinishedRestoreKey]; - _recorderResults = [coder decodeObjectOfClass:[NSArray class] forKey:_ORKRecorderResultsRestoreKey]; + _recorderResults = [coder decodeObjectOfClasses:[NSSet setWithArray:@[NSArray.self, ORKResult.self]] forKey:_ORKRecorderResultsRestoreKey]; } @end diff --git a/ResearchKitActiveTask/Common/Active Step/ORKActiveStepViewController_Internal.h b/ResearchKitActiveTask/Common/Active Step/ORKActiveStepViewController_Internal.h index 79b6c724b4..65dc15aff2 100644 --- a/ResearchKitActiveTask/Common/Active Step/ORKActiveStepViewController_Internal.h +++ b/ResearchKitActiveTask/Common/Active Step/ORKActiveStepViewController_Internal.h @@ -56,6 +56,8 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign, getter=isStarted) BOOL started; +@property (nonatomic, assign, getter=isNavigationFooterViewHidden) BOOL navigationFooterViewHidden; + - (void)countDownTimerFired:(ORKActiveStepTimer *)timer finished:(BOOL)finished; // Let subclass receive timer fires - (void)applicationWillResignActive:(NSNotification *)notification; diff --git a/ResearchKitActiveTask/Common/Active Step/Speech Synthesis/ORKVoiceEngine.h b/ResearchKitActiveTask/Common/Active Step/Speech Synthesis/ORKVoiceEngine.h index 3406ad640e..cc36b90c2e 100644 --- a/ResearchKitActiveTask/Common/Active Step/Speech Synthesis/ORKVoiceEngine.h +++ b/ResearchKitActiveTask/Common/Active Step/Speech Synthesis/ORKVoiceEngine.h @@ -29,8 +29,8 @@ */ -@import Foundation; -@import AVFoundation; +#import +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Common/Active Step/Timing/ORKActiveStepTimer.h b/ResearchKitActiveTask/Common/Active Step/Timing/ORKActiveStepTimer.h index d09548482c..09fd99f6d6 100644 --- a/ResearchKitActiveTask/Common/Active Step/Timing/ORKActiveStepTimer.h +++ b/ResearchKitActiveTask/Common/Active Step/Timing/ORKActiveStepTimer.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Common/Active Step/Views/ORKActiveStepTimerView.h b/ResearchKitActiveTask/Common/Active Step/Views/ORKActiveStepTimerView.h index 51eae5cb53..6c364b16cc 100644 --- a/ResearchKitActiveTask/Common/Active Step/Views/ORKActiveStepTimerView.h +++ b/ResearchKitActiveTask/Common/Active Step/Views/ORKActiveStepTimerView.h @@ -30,7 +30,8 @@ @import UIKit; -#import "ORKCustomStepView_Internal.h" + +#import "ORKActiveStepCustomView.h" NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Common/Active Step/Views/ORKActiveStepView.h b/ResearchKitActiveTask/Common/Active Step/Views/ORKActiveStepView.h index 635da6e240..31926ff83c 100644 --- a/ResearchKitActiveTask/Common/Active Step/Views/ORKActiveStepView.h +++ b/ResearchKitActiveTask/Common/Active Step/Views/ORKActiveStepView.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import diff --git a/ResearchKitActiveTask/Common/Active Step/Views/ORKActiveStepView.m b/ResearchKitActiveTask/Common/Active Step/Views/ORKActiveStepView.m index 0112e56d38..34ea74ed5c 100644 --- a/ResearchKitActiveTask/Common/Active Step/Views/ORKActiveStepView.m +++ b/ResearchKitActiveTask/Common/Active Step/Views/ORKActiveStepView.m @@ -31,7 +31,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKActiveStepView.h" -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" #import "ORKTintedImageView.h" #import "ORKStepContainerView_Private.h" diff --git a/ResearchKitActiveTask/Common/Countdown Step/ORKCountdownStep.h b/ResearchKitActiveTask/Common/Countdown Step/ORKCountdownStep.h index 1410a44a2c..d435e9982c 100644 --- a/ResearchKitActiveTask/Common/Countdown Step/ORKCountdownStep.h +++ b/ResearchKitActiveTask/Common/Countdown Step/ORKCountdownStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/Common/Countdown Step/ORKCountdownStepViewController.m b/ResearchKitActiveTask/Common/Countdown Step/ORKCountdownStepViewController.m index d014a75197..a43e964182 100644 --- a/ResearchKitActiveTask/Common/Countdown Step/ORKCountdownStepViewController.m +++ b/ResearchKitActiveTask/Common/Countdown Step/ORKCountdownStepViewController.m @@ -33,7 +33,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKActiveStepTimer.h" #import "ORKActiveStepView.h" -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" #import "ORKLabel.h" #import "ORKSubheadlineLabel.h" diff --git a/ResearchKitUI/Common/Step/ORKCustomStepView_Internal.h b/ResearchKitActiveTask/Common/Custom View/ORKActiveStepCustomView.h similarity index 97% rename from ResearchKitUI/Common/Step/ORKCustomStepView_Internal.h rename to ResearchKitActiveTask/Common/Custom View/ORKActiveStepCustomView.h index 5c25999861..8693e8abc7 100644 --- a/ResearchKitUI/Common/Step/ORKCustomStepView_Internal.h +++ b/ResearchKitActiveTask/Common/Custom View/ORKActiveStepCustomView.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2015, Apple Inc. All rights reserved. + Copyright (c) 2024, 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: @@ -28,7 +28,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #import @@ -51,4 +50,3 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END - diff --git a/ResearchKitActiveTask/Common/Custom View/ORKActiveStepCustomView.m b/ResearchKitActiveTask/Common/Custom View/ORKActiveStepCustomView.m new file mode 100644 index 0000000000..b806fa6557 --- /dev/null +++ b/ResearchKitActiveTask/Common/Custom View/ORKActiveStepCustomView.m @@ -0,0 +1,62 @@ +/* + Copyright (c) 2024, 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 "ORKActiveStepCustomView.h" + +#import "ORKActiveStepViewController.h" + +#import +#import +#import + +#import + + +@implementation ORKActiveStepCustomView + +- (void)resetStep:(ORKStepViewController *)viewController { +} + +- (void)startStep:(ORKStepViewController *)viewController { +} + +- (void)suspendStep:(ORKStepViewController *)viewController { +} + +- (void)resumeStep:(ORKStepViewController *)viewController { +} + +- (void)finishStep:(ORKStepViewController *)viewController { +} + +- (void)updateDisplay:(ORKActiveStepViewController *)viewController { +} + +@end diff --git a/ResearchKitActiveTask/Common/ORKOrderedTask+ORKPredefinedActiveTask.m b/ResearchKitActiveTask/Common/ORKOrderedTask+ORKPredefinedActiveTask.m index 77096ab1b8..efc65e67a4 100644 --- a/ResearchKitActiveTask/Common/ORKOrderedTask+ORKPredefinedActiveTask.m +++ b/ResearchKitActiveTask/Common/ORKOrderedTask+ORKPredefinedActiveTask.m @@ -48,6 +48,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKTouchAnywhereStep.h" #import "ORKFitnessStep.h" #import "ORKFormStep.h" +#import "ORKHealthQuantityTypeRecorder.h" #import "ORKNavigableOrderedTask.h" #import "ORKPSATStep.h" #import "ORKQuestionStep.h" diff --git a/ResearchKitActiveTask/Common/Recorders/Accelerometer/ORKAccelerometerRecorder.h b/ResearchKitActiveTask/Common/Recorders/Accelerometer/ORKAccelerometerRecorder.h index 72b4dabe19..296dfff5a9 100644 --- a/ResearchKitActiveTask/Common/Recorders/Accelerometer/ORKAccelerometerRecorder.h +++ b/ResearchKitActiveTask/Common/Recorders/Accelerometer/ORKAccelerometerRecorder.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import #import diff --git a/ResearchKitActiveTask/Common/Recorders/Audio/ORKAudioRecorder.h b/ResearchKitActiveTask/Common/Recorders/Audio/ORKAudioRecorder.h index 90e6239a6c..b98dd2abd0 100644 --- a/ResearchKitActiveTask/Common/Recorders/Audio/ORKAudioRecorder.h +++ b/ResearchKitActiveTask/Common/Recorders/Audio/ORKAudioRecorder.h @@ -29,8 +29,8 @@ */ -@import UIKit; -@import AVFoundation; +#import +#import #import diff --git a/ResearchKitActiveTask/Common/Recorders/Audio/ORKStreamingAudioRecorder.h b/ResearchKitActiveTask/Common/Recorders/Audio/ORKStreamingAudioRecorder.h index 3e6ba72a32..abeb66a042 100644 --- a/ResearchKitActiveTask/Common/Recorders/Audio/ORKStreamingAudioRecorder.h +++ b/ResearchKitActiveTask/Common/Recorders/Audio/ORKStreamingAudioRecorder.h @@ -29,8 +29,8 @@ */ -@import UIKit; -@import AVFoundation; +#import +#import #import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Common/Recorders/Device Motion/ORKDeviceMotionRecorder.h b/ResearchKitActiveTask/Common/Recorders/Device Motion/ORKDeviceMotionRecorder.h index fcd91ebd8c..e4d5be961e 100644 --- a/ResearchKitActiveTask/Common/Recorders/Device Motion/ORKDeviceMotionRecorder.h +++ b/ResearchKitActiveTask/Common/Recorders/Device Motion/ORKDeviceMotionRecorder.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import #import diff --git a/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthClinicalTypeRecorder.h b/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthClinicalTypeRecorder.h index d75b8c72bb..6d20ecdb54 100644 --- a/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthClinicalTypeRecorder.h +++ b/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthClinicalTypeRecorder.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import #import #import @@ -67,6 +67,47 @@ API_AVAILABLE(ios(12.0)) outputDirectory:(nullable NSURL *)outputDirectory NS_DESIGNATED_INITIALIZER API_AVAILABLE(ios(12.0)); @end + +ORK_CLASS_AVAILABLE +API_AVAILABLE(ios(12.0)) +@interface ORKHealthClinicalTypeRecorderConfiguration : ORKRecorderConfiguration + +/** + Returns an initialized health clinical type recorder configuration using the specified clinical type. + + This method is the designated initializer. + + @param identifier The unique identifier of the recorder configuration. + @param healthClinicalType The HKClinicalType that should be collected during the active task. + @param healthFHIRResourceType The HKFHIRResourceType that should be used as predicate while querying for the healthClinicalType. Providing a HKFHIRResourceType that does not correspond to a HKClinicalType will NOT generate any result. + + @return An initialized health clinical type recorder configuration. + */ +- (instancetype)initWithIdentifier:(NSString *)identifier + healthClinicalType:(HKClinicalType *)healthClinicalType + healthFHIRResourceType:(nullable HKFHIRResourceType)healthFHIRResourceType NS_DESIGNATED_INITIALIZER API_AVAILABLE(ios(12.0)); + +/** + Returns a new health clinical type recorder configuration initialized from data in the given unarchiver. + + @param aDecoder Coder from which to initialize the health clinical type recorder configuration. + + @return A new health clinical type recorder configuration. + */ +- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER; + +/** + The HKClinicalType to be collected from HealthKit. (read-only) + */ +@property (nonatomic, readonly, copy) HKClinicalType *healthClinicalType; + +/** + The HKFHIRResourceType to used as predicate for HKQuery. (read-only) + */ +@property (nonatomic, readonly, copy) HKFHIRResourceType healthFHIRResourceType; + +@end + #endif NS_ASSUME_NONNULL_END diff --git a/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthClinicalTypeRecorder.m b/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthClinicalTypeRecorder.m index 42cb651011..1ccd171be9 100644 --- a/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthClinicalTypeRecorder.m +++ b/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthClinicalTypeRecorder.m @@ -37,8 +37,8 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKDataLogger.h" #import "ORKRecorder_Private.h" #import "ORKRecorder_Internal.h" -#import "HKSample+ORKJSONDictionary.h" +#import @interface ORKHealthClinicalTypeRecorder () { ORKDataLogger *_logger; diff --git a/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthQuantityTypeRecorder.h b/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthQuantityTypeRecorder.h index 8f4b76f22b..d558d9a3e1 100644 --- a/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthQuantityTypeRecorder.h +++ b/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthQuantityTypeRecorder.h @@ -29,12 +29,14 @@ */ -@import UIKit; +#import #import NS_ASSUME_NONNULL_BEGIN +@class HKQuantityType; +@class HKUnit; @class ORKHealthQuantityTypeRecorder; @protocol ORKHealthQuantityTypeRecorderDelegate @@ -77,4 +79,54 @@ ORK_CLASS_AVAILABLE @end +/** + A configuration object that records data from a HealthKit quantity type during an active step. + + Before you can use this configuration, you must use Xcode to enable the appropriate HealthKit entitlement + for your app. + + HealthKit quantity type data is serialized to JSON and returned as an `ORKFileResult` object. + For details on the format, see `HKSample+ORKJSONDictionary`. + + To use a recorder, include its configuration in the `recorderConfigurations` property + of an `ORKActiveStep` object, include that step in a task, and present it with + a task view controller. + */ +ORK_CLASS_AVAILABLE +@interface ORKHealthQuantityTypeRecorderConfiguration : ORKRecorderConfiguration + +/** + Returns an initialized health quantity type recorder configuration using the specified quantity type and unit designation. + + This method is the designated initializer. + + @param identifier The unique identifier of the recorder configuration. + @param quantityType The quantity type that should be collected during the active task. + @param unit The unit for the data that should be collected and serialized. + + @return An initialized health quantity type recorder configuration. + */ +- (instancetype)initWithIdentifier:(NSString *)identifier healthQuantityType:(HKQuantityType *)quantityType unit:(HKUnit *)unit NS_DESIGNATED_INITIALIZER; + +/** + Returns a new health quantity type recorder configuration initialized from data in the given unarchiver. + + @param aDecoder Coder from which to initialize the health quantity type recorder configuration. + + @return A new health quantity type recorder configuration. + */ +- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER; + +/** + The quantity type to be collected from HealthKit. (read-only) + */ +@property (nonatomic, readonly, copy) HKQuantityType *quantityType; + +/** + The unit in which to serialize the data from HealthKit. (read-only) + */ +@property (nonatomic, readonly, copy) HKUnit *unit; + +@end + NS_ASSUME_NONNULL_END diff --git a/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthQuantityTypeRecorder.m b/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthQuantityTypeRecorder.m index e62486ad50..10ee4e0f2a 100644 --- a/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthQuantityTypeRecorder.m +++ b/ResearchKitActiveTask/Common/Recorders/Health/ORKHealthQuantityTypeRecorder.m @@ -34,8 +34,8 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKDataLogger.h" #import "ORKRecorder_Private.h" #import "ORKRecorder_Internal.h" -#import "HKSample+ORKJSONDictionary.h" +#import @interface ORKHealthQuantityTypeRecorder () { ORKDataLogger *_logger; diff --git a/ResearchKitActiveTask/Common/Recorders/Location/ORKLocationRecorder.h b/ResearchKitActiveTask/Common/Recorders/Location/ORKLocationRecorder.h index 7f8e8e04d5..c1b8ea77f9 100644 --- a/ResearchKitActiveTask/Common/Recorders/Location/ORKLocationRecorder.h +++ b/ResearchKitActiveTask/Common/Recorders/Location/ORKLocationRecorder.h @@ -29,8 +29,8 @@ */ -@import UIKit; -@import CoreLocation; +#import +#import #import diff --git a/ResearchKitActiveTask/Common/Recorders/Pedometer/ORKPedometerRecorder.h b/ResearchKitActiveTask/Common/Recorders/Pedometer/ORKPedometerRecorder.h index 1ff3334e3c..da2f73e506 100644 --- a/ResearchKitActiveTask/Common/Recorders/Pedometer/ORKPedometerRecorder.h +++ b/ResearchKitActiveTask/Common/Recorders/Pedometer/ORKPedometerRecorder.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import #import diff --git a/ResearchKitActiveTask/Common/Recorders/Touch/ORKTouchRecorder.h b/ResearchKitActiveTask/Common/Recorders/Touch/ORKTouchRecorder.h index cbf89156d8..d343a67b46 100644 --- a/ResearchKitActiveTask/Common/Recorders/Touch/ORKTouchRecorder.h +++ b/ResearchKitActiveTask/Common/Recorders/Touch/ORKTouchRecorder.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import #import @@ -54,4 +54,35 @@ ORK_CLASS_AVAILABLE @end +/** + The `ORKTouchRecorderConfiguration` is a recorder configuration class for + generating an `ORKTouchRecorder`. + + It is currently considered private, and is not used in any of the active tasks. + */ +ORK_CLASS_AVAILABLE +@interface ORKTouchRecorderConfiguration : ORKRecorderConfiguration + +/** + Returns an initialized touch recorder configuration. + + This method is the designated initializer. + + @param identifier The unique identifier of the recorder configuration. + + @return An initialized touch recorder configuration. + */ +- (instancetype)initWithIdentifier:(NSString *)identifier NS_DESIGNATED_INITIALIZER; + +/** + Returns a new touch recorder configuration initialized from data in the given unarchiver. + + @param aDecoder Coder from which to initialize the touch recorder configuration. + + @return A new touch recorder configuration. + */ +- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER; + +@end + NS_ASSUME_NONNULL_END diff --git a/ResearchKitActiveTask/Common/Touch Anywhere Step/ORKTouchAnywhereStepViewController.m b/ResearchKitActiveTask/Common/Touch Anywhere Step/ORKTouchAnywhereStepViewController.m index 335bf8759b..003610f57a 100644 --- a/ResearchKitActiveTask/Common/Touch Anywhere Step/ORKTouchAnywhereStepViewController.m +++ b/ResearchKitActiveTask/Common/Touch Anywhere Step/ORKTouchAnywhereStepViewController.m @@ -32,7 +32,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKTouchAnywhereStepViewController.h" #import "ORKActiveStepViewController_Internal.h" #import "ORKStepViewController_Internal.h" -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" #import "ORKLabel.h" #import "ORKActiveStepView.h" #import "ORKProgressView.h" diff --git a/ResearchKitActiveTask/Fitness/ORKFitnessContentView.h b/ResearchKitActiveTask/Fitness/ORKFitnessContentView.h index c6ac1a9dfe..5233348b3e 100644 --- a/ResearchKitActiveTask/Fitness/ORKFitnessContentView.h +++ b/ResearchKitActiveTask/Fitness/ORKFitnessContentView.h @@ -29,8 +29,8 @@ */ -#import "ORKCustomStepView_Internal.h" - +#import +#import "ORKActiveStepCustomView.h" NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Fitness/ORKFitnessStep.h b/ResearchKitActiveTask/Fitness/ORKFitnessStep.h index 91ff406e41..3a26147171 100644 --- a/ResearchKitActiveTask/Fitness/ORKFitnessStep.h +++ b/ResearchKitActiveTask/Fitness/ORKFitnessStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/Front Facing Camera/ORKFrontFacingCameraStepViewController.m b/ResearchKitActiveTask/Front Facing Camera/ORKFrontFacingCameraStepViewController.m index b2ca3ee16d..a85cb8ab7e 100644 --- a/ResearchKitActiveTask/Front Facing Camera/ORKFrontFacingCameraStepViewController.m +++ b/ResearchKitActiveTask/Front Facing Camera/ORKFrontFacingCameraStepViewController.m @@ -35,7 +35,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKActiveStepView.h" #import "ORKActiveStepViewController_Internal.h" -#import "ORKBorderedButton.h" #import "ORKCollectionResult_Private.h" #import "ORKFrontFacingCameraStep.h" #import "ORKFrontFacingCameraStepContentView.h" diff --git a/ResearchKitActiveTask/Hole Peg Test/Place Test/ORKHolePegTestPlaceContentView.h b/ResearchKitActiveTask/Hole Peg Test/Place Test/ORKHolePegTestPlaceContentView.h index cc025ca9e4..010db190bf 100644 --- a/ResearchKitActiveTask/Hole Peg Test/Place Test/ORKHolePegTestPlaceContentView.h +++ b/ResearchKitActiveTask/Hole Peg Test/Place Test/ORKHolePegTestPlaceContentView.h @@ -30,7 +30,7 @@ @import UIKit; -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" #import "ORKTypes.h" diff --git a/ResearchKitActiveTask/Hole Peg Test/Place Test/ORKHolePegTestPlaceStep.h b/ResearchKitActiveTask/Hole Peg Test/Place Test/ORKHolePegTestPlaceStep.h index 5c34a10fcb..bfc449ef5a 100644 --- a/ResearchKitActiveTask/Hole Peg Test/Place Test/ORKHolePegTestPlaceStep.h +++ b/ResearchKitActiveTask/Hole Peg Test/Place Test/ORKHolePegTestPlaceStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/Hole Peg Test/Remove Test/ORKHolePegTestRemoveContentView.h b/ResearchKitActiveTask/Hole Peg Test/Remove Test/ORKHolePegTestRemoveContentView.h index 71bb94c628..a8fb749b90 100644 --- a/ResearchKitActiveTask/Hole Peg Test/Remove Test/ORKHolePegTestRemoveContentView.h +++ b/ResearchKitActiveTask/Hole Peg Test/Remove Test/ORKHolePegTestRemoveContentView.h @@ -30,7 +30,7 @@ @import UIKit; -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" #import "ORKTypes.h" diff --git a/ResearchKitActiveTask/Hole Peg Test/Remove Test/ORKHolePegTestRemoveStep.h b/ResearchKitActiveTask/Hole Peg Test/Remove Test/ORKHolePegTestRemoveStep.h index e6a8fd132b..b50b090ae3 100644 --- a/ResearchKitActiveTask/Hole Peg Test/Remove Test/ORKHolePegTestRemoveStep.h +++ b/ResearchKitActiveTask/Hole Peg Test/Remove Test/ORKHolePegTestRemoveStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/Info.plist b/ResearchKitActiveTask/Info.plist new file mode 100644 index 0000000000..291294aca1 --- /dev/null +++ b/ResearchKitActiveTask/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + ResearchKitActiveTask + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ResearchKitActiveTask + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(ORK_FRAMEWORK_BUILD_NUMBER) + + diff --git a/ResearchKitActiveTask/ORKSpeechInNoise/ORKSpeechInNoiseContentView.h b/ResearchKitActiveTask/ORKSpeechInNoise/ORKSpeechInNoiseContentView.h index ede647c18f..56af96114f 100644 --- a/ResearchKitActiveTask/ORKSpeechInNoise/ORKSpeechInNoiseContentView.h +++ b/ResearchKitActiveTask/ORKSpeechInNoise/ORKSpeechInNoiseContentView.h @@ -29,8 +29,8 @@ */ -@import UIKit; -#import +#import +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/PSAT/ORKPSATContentView.h b/ResearchKitActiveTask/PSAT/ORKPSATContentView.h index a25e4278d4..099023cd26 100644 --- a/ResearchKitActiveTask/PSAT/ORKPSATContentView.h +++ b/ResearchKitActiveTask/PSAT/ORKPSATContentView.h @@ -31,7 +31,7 @@ @import UIKit; #import "ORKTypes.h" -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/PSAT/ORKPSATStep.h b/ResearchKitActiveTask/PSAT/ORKPSATStep.h index 04c715053c..049818bcc2 100644 --- a/ResearchKitActiveTask/PSAT/ORKPSATStep.h +++ b/ResearchKitActiveTask/PSAT/ORKPSATStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/PrivacyInfo.xcprivacy b/ResearchKitActiveTask/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..b181c500b6 --- /dev/null +++ b/ResearchKitActiveTask/PrivacyInfo.xcprivacy @@ -0,0 +1,84 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPITypeReasons + + 35F9.1 + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeAudioData + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypePhotosorVideos + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeSensitiveInfo + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeHealth + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypePreciseLocation + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + + diff --git a/ResearchKitActiveTask/Range of Motion/ORKRangeOfMotionStep.h b/ResearchKitActiveTask/Range of Motion/ORKRangeOfMotionStep.h index 4e247cd024..b4cbfa1565 100644 --- a/ResearchKitActiveTask/Range of Motion/ORKRangeOfMotionStep.h +++ b/ResearchKitActiveTask/Range of Motion/ORKRangeOfMotionStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import #import diff --git a/ResearchKitActiveTask/Range of Motion/ORKRangeOfMotionStepViewController.m b/ResearchKitActiveTask/Range of Motion/ORKRangeOfMotionStepViewController.m index ca6d2b2b1c..fe6d6f83a6 100644 --- a/ResearchKitActiveTask/Range of Motion/ORKRangeOfMotionStepViewController.m +++ b/ResearchKitActiveTask/Range of Motion/ORKRangeOfMotionStepViewController.m @@ -31,7 +31,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKRangeOfMotionStepViewController.h" -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" #import "ORKHelpers_Internal.h" #import "ORKActiveStepViewController_Internal.h" #import "ORKStepViewController_Internal.h" diff --git a/ResearchKitActiveTask/Reaction Time/Normalized/ORKNormalizedReactionTimeContentView.h b/ResearchKitActiveTask/Reaction Time/Normalized/ORKNormalizedReactionTimeContentView.h index a5dbd1a00b..a0ba38833a 100644 --- a/ResearchKitActiveTask/Reaction Time/Normalized/ORKNormalizedReactionTimeContentView.h +++ b/ResearchKitActiveTask/Reaction Time/Normalized/ORKNormalizedReactionTimeContentView.h @@ -31,7 +31,7 @@ @import UIKit; -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" #import "ORKNormalizedReactionTimeStimulusView.h" #import "ORKRoundTappingButton.h" diff --git a/ResearchKitActiveTask/Reaction Time/Normalized/ORKNormalizedReactionTimeStimulusView.h b/ResearchKitActiveTask/Reaction Time/Normalized/ORKNormalizedReactionTimeStimulusView.h index a738a500f4..8ca2edf051 100644 --- a/ResearchKitActiveTask/Reaction Time/Normalized/ORKNormalizedReactionTimeStimulusView.h +++ b/ResearchKitActiveTask/Reaction Time/Normalized/ORKNormalizedReactionTimeStimulusView.h @@ -31,7 +31,8 @@ @import UIKit; -#import "ORKCustomStepView_Internal.h" + +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Reaction Time/Normalized/ORKNormalizedReactionTimeViewController.h b/ResearchKitActiveTask/Reaction Time/Normalized/ORKNormalizedReactionTimeViewController.h index 8dbfd1e943..eb2c7549ca 100644 --- a/ResearchKitActiveTask/Reaction Time/Normalized/ORKNormalizedReactionTimeViewController.h +++ b/ResearchKitActiveTask/Reaction Time/Normalized/ORKNormalizedReactionTimeViewController.h @@ -30,7 +30,7 @@ */ -@import UIKit; +#import #import #import diff --git a/ResearchKitActiveTask/Reaction Time/ORKReactionTimeContentView.h b/ResearchKitActiveTask/Reaction Time/ORKReactionTimeContentView.h index 64bf1eefee..d0f7622417 100644 --- a/ResearchKitActiveTask/Reaction Time/ORKReactionTimeContentView.h +++ b/ResearchKitActiveTask/Reaction Time/ORKReactionTimeContentView.h @@ -30,7 +30,8 @@ @import UIKit; -#import "ORKCustomStepView_Internal.h" + +#import "ORKActiveStepCustomView.h" NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Reaction Time/ORKReactionTimeStep.h b/ResearchKitActiveTask/Reaction Time/ORKReactionTimeStep.h index 891d439992..b1927d06ba 100644 --- a/ResearchKitActiveTask/Reaction Time/ORKReactionTimeStep.h +++ b/ResearchKitActiveTask/Reaction Time/ORKReactionTimeStep.h @@ -29,8 +29,8 @@ */ -@import Foundation; -@import AudioToolbox; +#import +#import #import #import diff --git a/ResearchKitActiveTask/Reaction Time/ORKReactionTimeStimulusView.h b/ResearchKitActiveTask/Reaction Time/ORKReactionTimeStimulusView.h index ac3b926dd7..8b616c5581 100644 --- a/ResearchKitActiveTask/Reaction Time/ORKReactionTimeStimulusView.h +++ b/ResearchKitActiveTask/Reaction Time/ORKReactionTimeStimulusView.h @@ -30,7 +30,8 @@ @import UIKit; -#import "ORKCustomStepView_Internal.h" + +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/ResearchKitActiveTask.h b/ResearchKitActiveTask/ResearchKitActiveTask.h index 5c5ff2dcdf..3c2457b07b 100644 --- a/ResearchKitActiveTask/ResearchKitActiveTask.h +++ b/ResearchKitActiveTask/ResearchKitActiveTask.h @@ -43,6 +43,7 @@ FOUNDATION_EXPORT const unsigned char ResearchKitActiveTaskVersionString[]; #import #import #import +#import #import #import #import diff --git a/ResearchKitActiveTask/ResearchKitActiveTask.modulemap b/ResearchKitActiveTask/ResearchKitActiveTask.modulemap index 33bc5ca7f7..d191f79660 100644 --- a/ResearchKitActiveTask/ResearchKitActiveTask.modulemap +++ b/ResearchKitActiveTask/ResearchKitActiveTask.modulemap @@ -4,10 +4,3 @@ framework module ResearchKitActiveTask { export * module * { export * } } - -framework module ResearchKitActiveTask_Private { - umbrella header "ResearchKitActiveTask_Private.h" - - export * - module * { export * } -} diff --git a/ResearchKitActiveTask/ResearchKitActiveTask_Private.modulemap b/ResearchKitActiveTask/ResearchKitActiveTask_Private.modulemap new file mode 100644 index 0000000000..93531c9bfb --- /dev/null +++ b/ResearchKitActiveTask/ResearchKitActiveTask_Private.modulemap @@ -0,0 +1,36 @@ +/* + Copyright (c) 2024, 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. + */ + +framework module ResearchKitActiveTask_Private { + umbrella header "ResearchKitActiveTask_Private.h" + + export * + module * { export * } +} diff --git a/ResearchKitActiveTask/Spatial Span Memory/ORKSpatialSpanMemoryContentView.h b/ResearchKitActiveTask/Spatial Span Memory/ORKSpatialSpanMemoryContentView.h index 0a0a2b94e3..49b77d62af 100644 --- a/ResearchKitActiveTask/Spatial Span Memory/ORKSpatialSpanMemoryContentView.h +++ b/ResearchKitActiveTask/Spatial Span Memory/ORKSpatialSpanMemoryContentView.h @@ -29,7 +29,7 @@ */ -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" #import "ORKSpatialSpanTargetView.h" #import "ORKBorderedButton.h" diff --git a/ResearchKitActiveTask/Spatial Span Memory/ORKSpatialSpanMemoryStep.h b/ResearchKitActiveTask/Spatial Span Memory/ORKSpatialSpanMemoryStep.h index dbb4a3e260..af9e384fcd 100644 --- a/ResearchKitActiveTask/Spatial Span Memory/ORKSpatialSpanMemoryStep.h +++ b/ResearchKitActiveTask/Spatial Span Memory/ORKSpatialSpanMemoryStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/SpeechRecognition/ORKSpeechRecognitionContentView.h b/ResearchKitActiveTask/SpeechRecognition/ORKSpeechRecognitionContentView.h index 015c42276c..3f37e0e8d2 100644 --- a/ResearchKitActiveTask/SpeechRecognition/ORKSpeechRecognitionContentView.h +++ b/ResearchKitActiveTask/SpeechRecognition/ORKSpeechRecognitionContentView.h @@ -28,9 +28,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - +#import #import -#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/SpeechRecognition/ORKSpeechRecognitionStepViewController.m b/ResearchKitActiveTask/SpeechRecognition/ORKSpeechRecognitionStepViewController.m index c8155f8757..dce2749047 100644 --- a/ResearchKitActiveTask/SpeechRecognition/ORKSpeechRecognitionStepViewController.m +++ b/ResearchKitActiveTask/SpeechRecognition/ORKSpeechRecognitionStepViewController.m @@ -51,7 +51,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKSpeechRecognitionError.h" #import "ORKHelpers_Internal.h" -#import "ORKBorderedButton.h" #import "ORKRecordButton.h" #import "ORKSpeechRecognitionResult.h" #import "ORKResult_Private.h" diff --git a/ResearchKitActiveTask/Stroop/ORKStroopContentView.h b/ResearchKitActiveTask/Stroop/ORKStroopContentView.h index ebcf863422..844cbfee38 100644 --- a/ResearchKitActiveTask/Stroop/ORKStroopContentView.h +++ b/ResearchKitActiveTask/Stroop/ORKStroopContentView.h @@ -31,7 +31,7 @@ @import UIKit; -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Stroop/ORKStroopStepViewController.m b/ResearchKitActiveTask/Stroop/ORKStroopStepViewController.m index cbf9f496ac..34e5313d1b 100644 --- a/ResearchKitActiveTask/Stroop/ORKStroopStepViewController.m +++ b/ResearchKitActiveTask/Stroop/ORKStroopStepViewController.m @@ -39,7 +39,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKCollectionResult_Private.h" #import "ORKStroopStep.h" #import "ORKHelpers_Internal.h" -#import "ORKBorderedButton.h" #import "ORKNavigationContainerView_Internal.h" diff --git a/ResearchKitActiveTask/Tapping/ORKTappingContentView.h b/ResearchKitActiveTask/Tapping/ORKTappingContentView.h index f22417bb08..5443fb16af 100644 --- a/ResearchKitActiveTask/Tapping/ORKTappingContentView.h +++ b/ResearchKitActiveTask/Tapping/ORKTappingContentView.h @@ -30,7 +30,8 @@ @import UIKit; -#import "ORKCustomStepView_Internal.h" + +#import "ORKActiveStepCustomView.h" NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Tapping/ORKTappingIntervalStep.h b/ResearchKitActiveTask/Tapping/ORKTappingIntervalStep.h index c0b5a294e1..4ad39ab1c7 100644 --- a/ResearchKitActiveTask/Tapping/ORKTappingIntervalStep.h +++ b/ResearchKitActiveTask/Tapping/ORKTappingIntervalStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/Tone Audiometry/ORKToneAudiometryContentView.h b/ResearchKitActiveTask/Tone Audiometry/ORKToneAudiometryContentView.h index 60c09cd379..ee2be6cbda 100644 --- a/ResearchKitActiveTask/Tone Audiometry/ORKToneAudiometryContentView.h +++ b/ResearchKitActiveTask/Tone Audiometry/ORKToneAudiometryContentView.h @@ -30,7 +30,8 @@ @import UIKit; -#import "ORKCustomStepView_Internal.h" + +#import "ORKActiveStepCustomView.h" NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Tone Audiometry/ORKToneAudiometryStep.h b/ResearchKitActiveTask/Tone Audiometry/ORKToneAudiometryStep.h index 1ebd771534..504635d0ee 100644 --- a/ResearchKitActiveTask/Tone Audiometry/ORKToneAudiometryStep.h +++ b/ResearchKitActiveTask/Tone Audiometry/ORKToneAudiometryStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityContentView.h b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityContentView.h index 97db7be35c..5f75b4a3b0 100644 --- a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityContentView.h +++ b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityContentView.h @@ -29,9 +29,9 @@ */ -@import UIKit; +#import -#import +#import #import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityLongPressStep.h b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityLongPressStep.h index 32320535b8..8311aad567 100644 --- a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityLongPressStep.h +++ b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityLongPressStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityPinchStep.h b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityPinchStep.h index 59be05529c..d02b8311c4 100644 --- a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityPinchStep.h +++ b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityPinchStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityRotationStep.h b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityRotationStep.h index 38b3561f1c..15bc1d2498 100644 --- a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityRotationStep.h +++ b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityRotationStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityScrollContentView.h b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityScrollContentView.h index 77a3638f25..4b220c0b85 100644 --- a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityScrollContentView.h +++ b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityScrollContentView.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import #import #import diff --git a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityScrollStep.h b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityScrollStep.h index 51953f1cc0..25c7ee366f 100644 --- a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityScrollStep.h +++ b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityScrollStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilitySwipeStep.h b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilitySwipeStep.h index e43fe000b5..651525439f 100644 --- a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilitySwipeStep.h +++ b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilitySwipeStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityTapContentView.h b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityTapContentView.h index 551dd00e66..92ef281e3b 100644 --- a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityTapContentView.h +++ b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityTapContentView.h @@ -30,7 +30,9 @@ @import UIKit; + #import "ORKTouchAbilityContentView.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityTapStep.h b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityTapStep.h index eb2464915e..0def89dc07 100644 --- a/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityTapStep.h +++ b/ResearchKitActiveTask/Touch Ability/ORKTouchAbilityTapStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/TowerOfHanoi/ORKTowerOfHanoiStep.h b/ResearchKitActiveTask/TowerOfHanoi/ORKTowerOfHanoiStep.h index 21ddf6ff34..a3a4699e77 100644 --- a/ResearchKitActiveTask/TowerOfHanoi/ORKTowerOfHanoiStep.h +++ b/ResearchKitActiveTask/TowerOfHanoi/ORKTowerOfHanoiStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/TowerOfHanoi/ORKTowerOfHanoiStepViewController.m b/ResearchKitActiveTask/TowerOfHanoi/ORKTowerOfHanoiStepViewController.m index efe18487ce..8d4f2bb476 100644 --- a/ResearchKitActiveTask/TowerOfHanoi/ORKTowerOfHanoiStepViewController.m +++ b/ResearchKitActiveTask/TowerOfHanoi/ORKTowerOfHanoiStepViewController.m @@ -32,7 +32,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKTowerOfHanoiStepViewController.h" #import "ORKActiveStepView.h" -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" #import "ORKTowerOfHanoiTowerView.h" #import "ORKActiveStepViewController_Internal.h" diff --git a/ResearchKitActiveTask/Trailmaking/ORKTrailmakingContentView.h b/ResearchKitActiveTask/Trailmaking/ORKTrailmakingContentView.h index f49229b372..79d76ac3ba 100644 --- a/ResearchKitActiveTask/Trailmaking/ORKTrailmakingContentView.h +++ b/ResearchKitActiveTask/Trailmaking/ORKTrailmakingContentView.h @@ -30,7 +30,8 @@ @import UIKit; -#import "ORKCustomStepView_Internal.h" + +#import "ORKActiveStepCustomView.h" NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/Trailmaking/ORKTrailmakingStep.h b/ResearchKitActiveTask/Trailmaking/ORKTrailmakingStep.h index b58570156b..6f89ed26a5 100644 --- a/ResearchKitActiveTask/Trailmaking/ORKTrailmakingStep.h +++ b/ResearchKitActiveTask/Trailmaking/ORKTrailmakingStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/Trailmaking/ORKTrailmakingStepViewController.m b/ResearchKitActiveTask/Trailmaking/ORKTrailmakingStepViewController.m index 828104c82b..aa7482a5ee 100644 --- a/ResearchKitActiveTask/Trailmaking/ORKTrailmakingStepViewController.m +++ b/ResearchKitActiveTask/Trailmaking/ORKTrailmakingStepViewController.m @@ -34,7 +34,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKActiveStepTimer.h" #import "ORKActiveStepView.h" #import "ORKTrailmakingContentView.h" -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" #import "ORKRoundTappingButton.h" #import "ORKActiveStepViewController_Internal.h" diff --git a/ResearchKitActiveTask/Walking/Short Walk/ORKWalkingTaskStep.h b/ResearchKitActiveTask/Walking/Short Walk/ORKWalkingTaskStep.h index 5a351a7d0f..cffe77143a 100644 --- a/ResearchKitActiveTask/Walking/Short Walk/ORKWalkingTaskStep.h +++ b/ResearchKitActiveTask/Walking/Short Walk/ORKWalkingTaskStep.h @@ -29,7 +29,7 @@ */ -@import Foundation; +#import #import #import diff --git a/ResearchKitActiveTask/Walking/Short Walk/ORKWalkingTaskStepViewController.m b/ResearchKitActiveTask/Walking/Short Walk/ORKWalkingTaskStepViewController.m index cfc1696074..3c58d3a3b6 100644 --- a/ResearchKitActiveTask/Walking/Short Walk/ORKWalkingTaskStepViewController.m +++ b/ResearchKitActiveTask/Walking/Short Walk/ORKWalkingTaskStepViewController.m @@ -32,7 +32,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKWalkingTaskStepViewController.h" #import "ORKActiveStepView.h" -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" #import "ORKProgressView.h" #import "ORKVerticalContainerView_Internal.h" diff --git a/ResearchKitActiveTask/Walking/Timed Walk/ORKTimedWalkContentView.h b/ResearchKitActiveTask/Walking/Timed Walk/ORKTimedWalkContentView.h index 49f87676a4..bc6a922cc4 100644 --- a/ResearchKitActiveTask/Walking/Timed Walk/ORKTimedWalkContentView.h +++ b/ResearchKitActiveTask/Walking/Timed Walk/ORKTimedWalkContentView.h @@ -30,7 +30,8 @@ @import UIKit; -#import "ORKCustomStepView_Internal.h" + +#import "ORKActiveStepCustomView.h" NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKAudiometry.h b/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKAudiometry.h index 13f3397704..eede1d774d 100644 --- a/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKAudiometry.h +++ b/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKAudiometry.h @@ -28,7 +28,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -@import UIKit; +#import #import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryAudioGenerator.h b/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryAudioGenerator.h index bda06288ef..3e4a4ac399 100644 --- a/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryAudioGenerator.h +++ b/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryAudioGenerator.h @@ -51,8 +51,8 @@ */ -@import UIKit; -@import AVFoundation; +#import +#import #import diff --git a/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryAudioGenerator.m b/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryAudioGenerator.m index 641d79b134..007a3b69e0 100644 --- a/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryAudioGenerator.m +++ b/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryAudioGenerator.m @@ -59,6 +59,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ORKVolumeCurveFilename const ORKVolumeCurveFilenameAirPods = @"volume_curve_AIRPODS"; ORKVolumeCurveFilename const ORKVolumeCurveFilenameAirPodsGen3 = @"volume_curve_AIRPODSV3"; ORKVolumeCurveFilename const ORKVolumeCurveFilenameAirPodsPro = @"volume_curve_AIRPODSPRO"; +ORKVolumeCurveFilename const ORKVolumeCurveFilenameAirPodsProGen2 = @"volume_curve_AIRPODSPROV2"; ORKVolumeCurveFilename const ORKVolumeCurveFilenameAirPodsMax = @"volume_curve_AIRPODSMAX"; ORKVolumeCurveFilename const ORKVolumeCurveFilenameWired = @"volume_curve_WIRED"; @@ -196,6 +197,9 @@ - (instancetype)initForHeadphoneType:(ORKHeadphoneTypeIdentifier)headphoneType { } else if ([headphoneTypeUppercased isEqualToString:ORKHeadphoneTypeIdentifierAirPodsPro]) { headphoneTypeIdentifier = ORKHeadphoneTypeIdentifierAirPodsPro; volumeCurveFilename = ORKVolumeCurveFilenameAirPodsPro; + } else if ([headphoneTypeUppercased isEqualToString:ORKHeadphoneTypeIdentifierAirPodsProGen2]) { + headphoneTypeIdentifier = ORKHeadphoneTypeIdentifierAirPodsProGen2; + volumeCurveFilename = ORKVolumeCurveFilenameAirPodsProGen2; } else if ([headphoneTypeUppercased isEqualToString:ORKHeadphoneTypeIdentifierAirPodsMax]) { headphoneTypeIdentifier = ORKHeadphoneTypeIdentifierAirPodsMax; volumeCurveFilename = ORKVolumeCurveFilenameAirPodsMax; @@ -206,11 +210,11 @@ - (instancetype)initForHeadphoneType:(ORKHeadphoneTypeIdentifier)headphoneType { @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"A valid headphone route identifier must be provided" userInfo:nil]; } - _sensitivityPerFrequency = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForResource:[NSString stringWithFormat:frequencydBSPLBaseFilename, headphoneTypeIdentifier] ofType:filenameExtension]]; + _sensitivityPerFrequency = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle bundleForClass:[ORKdBHLToneAudiometryAudioGenerator class]] pathForResource:[NSString stringWithFormat:frequencydBSPLBaseFilename, headphoneTypeIdentifier] ofType:filenameExtension]]; - _retspl = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForResource:[NSString stringWithFormat:retsplBaseFilename, headphoneTypeIdentifier] ofType:filenameExtension]]; + _retspl = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle bundleForClass:[ORKdBHLToneAudiometryAudioGenerator class]] pathForResource:[NSString stringWithFormat:retsplBaseFilename, headphoneTypeIdentifier] ofType:filenameExtension]]; - _volumeCurve = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForResource:volumeCurveFilename ofType:filenameExtension]]; + _volumeCurve = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle bundleForClass:[ORKdBHLToneAudiometryAudioGenerator class]] pathForResource:volumeCurveFilename ofType:filenameExtension]]; [self setupGraph]; } diff --git a/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryContentView.h b/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryContentView.h index f78a3afac7..a2ed8b794f 100644 --- a/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryContentView.h +++ b/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryContentView.h @@ -31,7 +31,7 @@ @import UIKit; -#import "ORKCustomStepView_Internal.h" +#import "ORKActiveStepCustomView.h" #import "ORKUnitLabel.h" #import "ORKRoundTappingButton.h" diff --git a/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryStepViewController.m b/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryStepViewController.m index 51d17b7404..c6aab78aa9 100644 --- a/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryStepViewController.m +++ b/ResearchKitActiveTask/dBHL Tone Audiometry/ORKAudiometry/ORKdBHLToneAudiometryStepViewController.m @@ -108,7 +108,6 @@ - (ORKdBHLToneAudiometryStep *)dBHLToneAudiometryStep { - (void)viewDidLoad { [super viewDidLoad]; - [self configureStep]; } - (ORKdBHLToneAudiometryAudioGenerator *)createAudioGeneratorFromHeadphoneType:(ORKHeadphoneTypeIdentifier)type { @@ -142,6 +141,11 @@ - (void)removeObservers { [center removeObserver:self name:UIApplicationWillTerminateNotification object:nil]; } +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [self configureStep]; +} + - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; diff --git a/ResearchKitActiveTask/environmentSPLMeter/ORKEnvironmentSPLMeterContentView.h b/ResearchKitActiveTask/environmentSPLMeter/ORKEnvironmentSPLMeterContentView.h index 44095d8811..bc75033b6c 100644 --- a/ResearchKitActiveTask/environmentSPLMeter/ORKEnvironmentSPLMeterContentView.h +++ b/ResearchKitActiveTask/environmentSPLMeter/ORKEnvironmentSPLMeterContentView.h @@ -29,7 +29,7 @@ */ @import UIKit; -#import "ORKCustomStepView_Internal.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitTests/ORKESerialization.m b/ResearchKitTests/ORKESerialization.m index 9e9b78795a..e49aeb78bd 100644 --- a/ResearchKitTests/ORKESerialization.m +++ b/ResearchKitTests/ORKESerialization.m @@ -644,6 +644,7 @@ - (instancetype)initWithLocalizer:(nullable id)local static id propFromDict(NSDictionary *dict, NSString *propName, ORKESerializationContext *context) { Class class = NSClassFromString(dict[_ClassKey]); + NSArray *classEncodings = classEncodingsForClass(class); ORKESerializableProperty *propertyEntry = nil; for (ORKESerializableTableEntry *classEncoding in classEncodings) { @@ -918,7 +919,8 @@ @implementation ORKESerializer image:nil learnMoreItem:GETPROP(dict, learnMoreItem) bodyItemStyle:[GETPROP(dict, bodyItemStyle) intValue] - useCardStyle:GETPROP(dict, useCardStyle)]; + useCardStyle:GETPROP(dict, useCardStyle) + alignImageToTop:GETPROP(dict, alignImageToTop)]; return bodyItem; }, (@{ @@ -929,6 +931,7 @@ @implementation ORKESerializer PROPERTY(learnMoreItem, ORKLearnMoreItem, NSObject, YES, nil, nil), PROPERTY(useCardStyle, NSNumber, NSObject, YES, nil, nil), PROPERTY(useSecondaryColor, NSNumber, NSObject, YES, nil, nil), + PROPERTY(alignImageToTop, NSNumber, NSObject, YES, nil, nil), })), ENTRY(ORKLearnMoreItem, ^id(__unused NSDictionary *dict, __unused ORKESerializationPropertyGetter getter) { @@ -1578,6 +1581,7 @@ @implementation ORKESerializer PROPERTY(formItems, ORKFormItem, NSArray, YES, nil, nil), PROPERTY(footnote, NSString, NSObject, YES, nil, nil), PROPERTY(useCardView, NSNumber, NSObject, YES, nil, nil), + PROPERTY(autoScrollEnabled, NSNumber, NSObject, YES, nil, nil), PROPERTY(footerText, NSString, NSObject, YES, nil, nil), PROPERTY(cardViewStyle, NSNumber, NSObject, YES, nil, nil), })), diff --git a/ResearchKitTests/ORKFormStepViewController+TestingSupport.h b/ResearchKitTests/ORKFormStepViewController+TestingSupport.h index 190a6f0698..76cf530a7d 100644 --- a/ResearchKitTests/ORKFormStepViewController+TestingSupport.h +++ b/ResearchKitTests/ORKFormStepViewController+TestingSupport.h @@ -30,6 +30,7 @@ #import +NS_ASSUME_NONNULL_BEGIN @class ORKTableCellItemIdentifier; @@ -68,4 +69,7 @@ returns a list of all the answerable formItems fetches the associated ORKFormItem from a formItemIdentifier (potential performance hit) */ - (nullable ORKFormItem *)_formItemForFormItemIdentifier:(NSString *)formItemIdentifier; + @end + +NS_ASSUME_NONNULL_END diff --git a/ResearchKitTests/ORKJSONSerializationTests.m b/ResearchKitTests/ORKJSONSerializationTests.m index a456598ec3..776a966314 100644 --- a/ResearchKitTests/ORKJSONSerializationTests.m +++ b/ResearchKitTests/ORKJSONSerializationTests.m @@ -40,7 +40,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKESerialization.h" #import -BOOL ORKIsResearchKitClass(Class class) { +static BOOL ORKIsResearchKitClass(Class class) { NSString *name = NSStringFromClass(class); return [name hasPrefix:@"ORK"]; } diff --git a/ResearchKitTests/ORKResultTests.m b/ResearchKitTests/ORKResultTests.m index 26afa0463e..f7841b914f 100644 --- a/ResearchKitTests/ORKResultTests.m +++ b/ResearchKitTests/ORKResultTests.m @@ -35,11 +35,23 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE @import ResearchKitUI_Private; @import ResearchKit_Private; +@interface ORKResultTestsHelper: NSObject +@end + +// For access to taskViewController's managed results +@interface ORKTaskViewController (Testing_Privates) + +- (void)setManagedResult:(ORKStepResult *)result forKey:(NSString *)aKey; +- (void)requestHealthStoreAccessWithReadTypes:(NSSet *)readTypes + writeTypes:(NSSet *)writeTypes + handler:(void (^)(void))handler; -@interface ORKResultTests : XCTestCase @end +@interface ORKResultTests : XCTestCase + +@end @implementation ORKResultTests @@ -125,10 +137,10 @@ - (void)compareTaskResult1:(ORKTaskResult *)taskResult1 andTaskResult2:(ORKTaskR - (void)testTaskViewControllerPrematureViewLoading { ORKOrderedTask *task = [[ORKOrderedTask alloc] initWithIdentifier:@"test" steps:@[ - [[ORKInstructionStep alloc] initWithIdentifier:@"test"] - ]]; + [[ORKInstructionStep alloc] initWithIdentifier:@"test"] + ]]; ORKTaskViewController *taskViewController = [[ORKTaskViewController alloc] initWithTask:task taskRunUUID:nil]; - ORKStepViewController *viewController = [task.steps.firstObject makeViewControllerWithResult:nil]; + ORKStepViewController *viewController = [((ORKOrderedTask *)ORKDynamicCast(taskViewController.task, ORKOrderedTask)).steps.firstObject makeViewControllerWithResult:nil]; XCTAssertFalse(viewController.isViewLoaded, "TaskViewController's viewControllerForStep should return a viewController *without* its view loaded"); } @@ -137,8 +149,8 @@ - (void)testResultSecureCoding { ORKTaskResult *taskResult1 = [self createTaskResultTree]; // Archive - id data = [NSKeyedArchiver archivedDataWithRootObject:taskResult1]; - NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; + id data = [NSKeyedArchiver archivedDataWithRootObject:taskResult1 requiringSecureCoding:YES error:nil];; + NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:nil]; unarchiver.requiresSecureCoding = YES; ORKTaskResult *taskResult2 = [unarchiver decodeObjectOfClass:[ORKTaskResult class] forKey:NSKeyedArchiveRootObjectKey]; @@ -175,7 +187,7 @@ - (void)testPageResult { NSArray *steps = @[[[ORKStep alloc] initWithIdentifier:@"step1"], [[ORKStep alloc] initWithIdentifier:@"step2"], [[ORKStep alloc] initWithIdentifier:@"step3"], - ]; + ]; ORKPageStep *pageStep = [[ORKPageStep alloc] initWithIdentifier:@"pageStep" steps:steps]; ORKChoiceQuestionResult *step1Result1 = [[ORKChoiceQuestionResult alloc] initWithIdentifier:@"step1.result1"]; @@ -186,7 +198,7 @@ - (void)testPageResult { step2Result1.choiceAnswers = @[ @(3) ]; ORKStepResult *inputResult = [[ORKStepResult alloc] initWithStepIdentifier:@"pageStep" - results:@[step1Result1, step1Result2, step2Result1]]; + results:@[step1Result1, step1Result2, step2Result1]]; // Test that the page result creates ORKStepResults for each result that matches the prefix test ORKPageResult *pageResult = [[ORKPageResult alloc] initWithPageStep:pageStep stepResult:inputResult]; @@ -243,4 +255,149 @@ - (void)testStepResultForStepIdentifierWithIdentifierMatchingORKResultExpectNil XCTAssertNil(result); } +- (void)testTaskViewControllerNullDataRestorationThrows { + NSData *taskData = [NSData data]; + ORKOrderedTask *task = [[ORKOrderedTask alloc] initWithIdentifier:@"test" steps:@[]]; + ORKResultTestsHelper *taskDelegate = [[ORKResultTestsHelper alloc] init]; + + ORKTaskViewController *taskViewController; + + @try { + NSError *error = nil; + taskViewController = [[ORKTaskViewController alloc] initWithTask:task restorationData:taskData delegate:taskDelegate error:&error]; + XCTFail("ORKTaskViewController init with bad restoration data should throw"); + } @catch (NSException *exception) { + XCTAssertEqual(NSInternalInconsistencyException, exception.name); + } +} + +- (void)testMutableDecoding { + NSMutableArray *things = [[NSMutableArray alloc] initWithObjects:@"hello", @"world", nil]; + __auto_type keyedArchiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + [keyedArchiver encodeObject:things forKey:@"mutableThings"]; + [keyedArchiver encodeObject:@[@"farewell"] forKey:@"immutableThings"]; + [keyedArchiver finishEncoding]; + + NSData *data = [keyedArchiver encodedData]; + __auto_type keyedUnarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:nil]; + NSSet *decodableTypes = [NSSet setWithObjects:NSMutableArray.self, NSString.self, nil]; + + { + // decoding an mutable array actually returns a mutable array + NSMutableArray *decodedArray = [keyedUnarchiver decodeObjectOfClasses:decodableTypes forKey:@"mutableThings"]; + XCTAssertTrue([decodedArray isKindOfClass:NSMutableArray.self], "decoding a mutable array should return a mutable array"); + + [decodedArray addObject:@"test"]; + XCTAssertEqual(decodedArray.count, 3); + XCTAssertEqualObjects(decodedArray.lastObject, @"test"); + } + + { + // decoding an immutable array as if it were mutable works, but should fail when using it as mutable + NSMutableArray *decodedArray = [keyedUnarchiver decodeObjectOfClasses:decodableTypes forKey:@"immutableThings"]; + XCTAssertFalse([decodedArray isKindOfClass:NSMutableArray.self], "decoding an immutable array should return an immutable array"); + XCTAssertTrue([decodedArray isKindOfClass:NSArray.self]); + XCTAssertThrows([decodedArray addObject:@"test"]); + } + +} + +- (void)testTaskViewControllerRestorationWorks { + ORKFormStep *formItemStep = [[ORKFormStep alloc] initWithIdentifier:@"step"]; + + formItemStep.formItems = @[ + [[ORKFormItem alloc] initWithIdentifier:@"item1" text:nil answerFormat:ORKAnswerFormat.booleanAnswerFormat], + [[ORKFormItem alloc] initWithIdentifier:@"item2" text:nil answerFormat:ORKAnswerFormat.textAnswerFormat], + [[ORKFormItem alloc] initWithIdentifier:@"item3" text:nil answerFormat:[ORKAnswerFormat integerAnswerFormatWithUnit:nil]] + ]; + ORKOrderedTask *task = [[ORKOrderedTask alloc] initWithIdentifier:@"test" steps:@[formItemStep]]; + + NSData *encodedTaskViewControllerData; + { + // create the task as if we were to present it + ORKTaskViewController *taskViewController = [[ORKTaskViewController alloc] initWithTask:task taskRunUUID:nil]; + + // Trigger requestHealth access to fill in the read/write types ivars + NSSet *readTypes = [NSSet setWithObjects:[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate], nil]; + NSSet *writeTypes = [NSSet setWithObjects:[HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierMenstrualFlow], nil]; + [taskViewController requestHealthStoreAccessWithReadTypes:readTypes writeTypes:writeTypes handler:^(){ + // intentionally left empty + }]; + + // viewWillAppear fills in the _managedStepIdentifiers in the taskViewController + [taskViewController viewWillAppear:false]; + + // make a few answers to test with, simulating answers entered by a user + __auto_type booleanAnswer = [[ORKBooleanQuestionResult alloc] initWithIdentifier:@"item1"]; + booleanAnswer.booleanAnswer = @(YES); + + __auto_type textAnswer = [[ORKTextQuestionResult alloc] initWithIdentifier:@"item2"]; + textAnswer.textAnswer = @"there is no answer, only questions"; + + __auto_type integerAnswer = [[ORKNumericQuestionResult alloc] initWithIdentifier:@"item3"]; + integerAnswer.numericAnswer = @(42); + + ORKStepResult *stepResult = [[ORKStepResult alloc] initWithStepIdentifier:@"step" results:@[ + booleanAnswer, textAnswer, integerAnswer + ]]; + // set the answers using taskViewController-internal method, to simulate user data entry + [taskViewController setManagedResult:stepResult forKey:@"step"]; + + // archive it + __auto_type keyedArchiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + [taskViewController encodeRestorableStateWithCoder:keyedArchiver]; + encodedTaskViewControllerData = [keyedArchiver encodedData]; + } + XCTAssertNotNil(encodedTaskViewControllerData); + + // init a new taskViewController with the restoration data + { + // important to start with the same task so the identifiers match + ORKResultTestsHelper *taskDelegate = [[ORKResultTestsHelper alloc] init]; + ORKTaskViewController *taskViewController = [[ORKTaskViewController alloc] initWithTask:task restorationData:encodedTaskViewControllerData delegate:taskDelegate error:nil]; + + // confirm the read/write HK type info made it across the encode/decode bridge + XCTAssertEqualObjects([taskViewController requestedHealthTypesForRead], [NSSet setWithObject:[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate]]); + XCTAssertEqualObjects([taskViewController requestedHealthTypesForWrite], [NSSet setWithObject:[HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierMenstrualFlow]]); + + ORKStepResult *stepResult = (ORKStepResult *)[[[taskViewController result] results] firstObject]; + NSArray *questionResults = (NSArray *)[stepResult results]; + XCTAssertEqual([questionResults count], 3); + + XCTAssertEqual(questionResults[0].answer, @(YES)); + XCTAssertEqual(questionResults[0].identifier, @"item1"); + XCTAssertEqualObjects(questionResults[1].answer, @"there is no answer, only questions"); + XCTAssertEqual(questionResults[1].identifier, @"item2"); + XCTAssertEqualObjects(questionResults[2].answer, @(42)); + XCTAssertEqual(questionResults[2].identifier, @"item3"); + } + +} + +- (void)testConsentDocumentDecoding { + ORKConsentDocument *document = [[ORKConsentDocument alloc] init]; + document.signatures = @[ + [[ORKConsentSignature alloc] init], + [[ORKConsentSignature alloc] init], + [[ORKConsentSignature alloc] init] + ]; + + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + [archiver encodeObject:document forKey:@"rootDocumet"]; + NSData *data = archiver.encodedData; + + NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:nil]; + unarchiver.requiresSecureCoding = true; + ORKConsentDocument *decodedDocument = [unarchiver decodeObjectOfClass:ORKConsentDocument.self forKey:@"rootDocumet"]; + XCTAssertEqual(decodedDocument.signatures.count, 3); +} + +@end + +@implementation ORKResultTestsHelper + +- (void)taskViewController:(ORKTaskViewController *)taskViewController didFinishWithReason:(ORKTaskFinishReason)reason error:(nullable NSError *)error { + // intentionally left empty +} + @end diff --git a/ResearchKitTests/ORKTaskViewControllerTests.swift b/ResearchKitTests/ORKTaskViewControllerTests.swift new file mode 100644 index 0000000000..95cf5d1f34 --- /dev/null +++ b/ResearchKitTests/ORKTaskViewControllerTests.swift @@ -0,0 +1,322 @@ +// +/* + Copyright (c) 2024, 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 +import ResearchKitUI +import XCTest + +enum ORKIdentifier: String { + case instructionStep1, + questionStep1, + questionStep2, + questionStep3, + questionStep4, + completionStep1, + orderedTask1 +} + +class FauxTaskViewController: NSObject, ORKTaskViewControllerDelegate { + + var expectation: XCTestExpectation? + + func taskViewController(_ taskViewController: ORKTaskViewController, didFinishWith reason: ORKTaskFinishReason, error: Error?) { + if reason == .completed { + expectation?.fulfill() + } + } + + func taskViewControllerSupportsSaveAndRestore(_ taskViewController: ORKTaskViewController) -> Bool { + return true + } +} + +final class ORKTaskViewControllerTests: XCTestCase { + + var taskCompletionExpectation: XCTestExpectation? + + var options = [ + ORKTextChoice( + text: "Banana", + value: 1 as NSCopying & NSSecureCoding & NSObjectProtocol + ), + ORKTextChoice( + text: "Lychee", + value: 2 as NSCopying & NSSecureCoding & NSObjectProtocol + ), + ORKTextChoice( + text: "Kiwi", + value: 3 as NSCopying & NSSecureCoding & NSObjectProtocol + ), + ORKTextChoice( + text: "Orange", + value: 4 as NSCopying & NSSecureCoding & NSObjectProtocol + ), + ] + + override func setUpWithError() throws { + try super.setUpWithError() + + taskCompletionExpectation = nil + + taskCompletionExpectation = XCTestExpectation(description: "TaskCompletion") + + } + + func createTask() -> ORKOrderedTask { + // Step 1 + let instructionStep1 = ORKInstructionStep(identifier: ORKIdentifier.instructionStep1.rawValue) + + // Step 2 + let q1AnswerFormat = ORKNumericAnswerFormat(style: .integer) + + let questionStep1 = ORKQuestionStep( + identifier: ORKIdentifier.questionStep1.rawValue, + title: "First Question Title", + question: "What is your age?", + answer: q1AnswerFormat + ) + + // Step 3 + let q2AnswerFormat = ORKTextAnswerFormat() + + let questionStep2 = ORKQuestionStep( + identifier: ORKIdentifier.questionStep2.rawValue, + title: "Title for Second Question", + question: "What is your name?", + answer: q2AnswerFormat + ) + + // Step 4 + let q3AnswerFormat = ORKTextChoiceAnswerFormat( + style: .singleChoice, + textChoices: options + ) + + let questionStep3 = ORKQuestionStep( + identifier: ORKIdentifier.questionStep3.rawValue, + title: "Question 3", + question: "What is your favorite fruit?", + answer: q3AnswerFormat + ) + + // Step 5 + let q4AnswerFormat = ORKScaleAnswerFormat( + maximumValue: 10, + minimumValue: 1, + defaultValue: 5, + step: 1 + ) + + let questionStep4 = ORKQuestionStep( + identifier: ORKIdentifier.questionStep4.rawValue, + title: "Question 4", + question: "How many fingers do you have?", + answer: q4AnswerFormat + ) + + // Step 6 + let completionStep1 = ORKCompletionStep( + identifier: ORKIdentifier.completionStep1.rawValue + ) + + let task = ORKOrderedTask( + identifier: ORKIdentifier.orderedTask1.rawValue, + steps: [ + instructionStep1, + questionStep1, + questionStep2, + questionStep3, + questionStep4, + completionStep1, + ] + ) + return task + } + + func testTaskSerialization() { + + let task = createTask() + let taskRunUUID = UUID() + let initialTaskViewController = ORKTaskViewController( + task: task, + taskRun: taskRunUUID + ) + let delegate = FauxTaskViewController() + delegate.expectation = taskCompletionExpectation + initialTaskViewController.delegate = delegate + + mockPresentTaskViewController(taskViewController: initialTaskViewController) + + wait(for: [taskCompletionExpectation!], timeout: 2.0) + + guard let restoredData = initialTaskViewController.restorationData else { + XCTFail("Unable to get restoration data for task") + return + } + + let restoredTaskViewController = ORKTaskViewController( + task: task, + restorationData: restoredData, + delegate: FauxTaskViewController(), + error: nil + ) + + let initialResult = initialTaskViewController.result + let restoredResult = restoredTaskViewController.result + + XCTAssertEqual(initialTaskViewController.task?.identifier, restoredTaskViewController.task?.identifier) + XCTAssertEqual(initialResult.results?.count, restoredResult.results?.count) + + initialResult.results?.enumerated().forEach({ index, stepResult in + guard + let resCount = restoredResult.results?.count, + index < resCount, + let stepResult = stepResult as? ORKStepResult, + let restoredStepResult = restoredResult.results?[index] as? ORKStepResult + else { + XCTFail("Unable to get same result after restoring with data") + return + } + + XCTAssertEqual(stepResult.identifier, restoredStepResult.identifier) + + switch stepResult.identifier { + + case ORKIdentifier.instructionStep1.rawValue, ORKIdentifier.completionStep1.rawValue: + break + case ORKIdentifier.questionStep1.rawValue: + guard + let numericResult = stepResult.results?.first as? ORKNumericQuestionResult, + let restoredNumericResult = restoredStepResult.results?.first as? ORKNumericQuestionResult + else { + XCTFail("Incorrect step result format") + return + } + XCTAssertEqual(numericResult.numericAnswer, restoredNumericResult.numericAnswer) + + case ORKIdentifier.questionStep2.rawValue: + guard + let textResult = stepResult.results?.first as? ORKTextQuestionResult, + let restoredTextResult = restoredStepResult.results?.first as? ORKTextQuestionResult + else { + XCTFail("Incorrect step result format") + return + } + XCTAssertEqual(textResult.textAnswer, restoredTextResult.textAnswer) + + case ORKIdentifier.questionStep3.rawValue: + guard + let choiceResult = stepResult.results?.first as? ORKChoiceQuestionResult, + let restoredChoiceResult = restoredStepResult.results?.first as? ORKChoiceQuestionResult + else { + XCTFail("Incorrect step result format") + return + } + XCTAssertEqual(choiceResult.answer as? Int, restoredChoiceResult.answer as? Int) + + case ORKIdentifier.questionStep4.rawValue: + guard + let scaleResult = stepResult.results?.first as? ORKScaleQuestionResult, + let restoredScaleResult = restoredStepResult.results?.first as? ORKScaleQuestionResult + else { + XCTFail("Incorrect step result format") + return + } + XCTAssertEqual(scaleResult.scaleAnswer, restoredScaleResult.scaleAnswer) + default: + XCTFail("Unidentifiable step identifier") + } + }) + } + + func mockPresentTaskViewController(taskViewController: ORKTaskViewController) { + guard + let orderedTask = taskViewController.task as? ORKOrderedTask, + orderedTask.steps.isEmpty == false + else { + XCTFail("Incorrect number of steps in task") + return + } + + for step in orderedTask.steps { + taskViewController.flipToPage(withIdentifier: step.identifier, forward: true, animated: false) + + guard + let currentStepViewController = taskViewController.currentStepViewController + else { + XCTFail("Unable to find next StepViewController") + return + } + + switch step.identifier { + case ORKIdentifier.instructionStep1.rawValue, ORKIdentifier.completionStep1.rawValue: + break + case ORKIdentifier.questionStep1.rawValue: + let result = ORKNumericQuestionResult(identifier: step.identifier) + result.questionType = .integer + let answer = 31 as NSNumber + result.numericAnswer = answer + currentStepViewController.addResult(result) + + case ORKIdentifier.questionStep2.rawValue: + let result = ORKTextQuestionResult(identifier: step.identifier) + result.questionType = .text + let answer = "SAMPLETEXT" + result.textAnswer = answer + currentStepViewController.addResult(result) + + case ORKIdentifier.questionStep3.rawValue: + + let result = ORKChoiceQuestionResult(identifier: step.identifier) + result.questionType = .singleChoice + guard + let answer = options.last?.value + else { + return + } + result.choiceAnswers = [answer] + currentStepViewController.addResult(result) + + case ORKIdentifier.questionStep4.rawValue: + let result = ORKScaleQuestionResult(identifier: step.identifier) + result.questionType = .scale + let answer = 6 as NSNumber + result.scaleAnswer = answer + currentStepViewController.addResult(result) + + default: + XCTFail("Unidentifiable step identifier") + } + + taskViewController.stepViewController(currentStepViewController, didFinishWith: .forward) + } + } +} diff --git a/ResearchKitTests/samples.bundle/ORKBodyItem.json b/ResearchKitTests/samples.bundle/ORKBodyItem.json index 2deaa98573..be8606de3f 100644 --- a/ResearchKitTests/samples.bundle/ORKBodyItem.json +++ b/ResearchKitTests/samples.bundle/ORKBodyItem.json @@ -1 +1 @@ -{"text":"","learnMoreItem":{"_class":"ORKLearnMoreItem"},"bodyItemStyle":0,"_class":"ORKBodyItem","detailText":"","image":{"imageName":"55324853-4B02-4BC2-B295-C42B8D9D814D"},"useCardStyle":0, "useSecondaryColor":0} +{"text":"","learnMoreItem":{"_class":"ORKLearnMoreItem"},"bodyItemStyle":0,"_class":"ORKBodyItem","detailText":"","image":{"imageName":"55324853-4B02-4BC2-B295-C42B8D9D814D"},"useCardStyle":0, "useSecondaryColor":0, "alignImageToTop":0} diff --git a/ResearchKitTests/samples.bundle/ORKFormStep.json b/ResearchKitTests/samples.bundle/ORKFormStep.json index bcf93bf4ae..4a1ed41e6f 100644 --- a/ResearchKitTests/samples.bundle/ORKFormStep.json +++ b/ResearchKitTests/samples.bundle/ORKFormStep.json @@ -1 +1 @@ -{"bodyItems":[],"detailText":"", "headerTextAlignment": 0, "optional":true,"useSurveyMode":true,"shouldTintImages":true,"_class":"ORKFormStep","auxiliaryImage":{"imageName":"747C6BFD-53E7-47EE-95B6-D4ABDC6270CF"},"iconImage":{"imageName":"A9782DB7-4168-4967-8E34-F75A62A7106E"},"title":"","identifier":"","footnote":"","shouldAutomaticallyAdjustImageTintColor":0,"image":{"imageName":"0BBE4F43-391F-4B33-9770-740363779CBD"},"text":"","formItems":[],"useCardView":true,"imageContentMode": 0,"footerText":"","bodyItemTextAlignment":0,"buildInBodyItems": 0,"cardViewStyle":0,"useExtendedPadding":0,"earlyTerminationConfiguration": {"_class": "ORKEarlyTerminationConfiguration"}} +{"bodyItems":[],"detailText":"", "headerTextAlignment": 0, "optional":true,"useSurveyMode":true,"shouldTintImages":true,"_class":"ORKFormStep","auxiliaryImage":{"imageName":"747C6BFD-53E7-47EE-95B6-D4ABDC6270CF"},"iconImage":{"imageName":"A9782DB7-4168-4967-8E34-F75A62A7106E"},"title":"","identifier":"","footnote":"","shouldAutomaticallyAdjustImageTintColor":0,"image":{"imageName":"0BBE4F43-391F-4B33-9770-740363779CBD"},"text":"","formItems":[],"useCardView":true,"autoScrollEnabled":true,"imageContentMode": 0,"footerText":"","bodyItemTextAlignment":0,"buildInBodyItems": 0,"cardViewStyle":0,"useExtendedPadding":0,"earlyTerminationConfiguration": {"_class": "ORKEarlyTerminationConfiguration"}} diff --git a/ResearchKitTests/samples.bundle/ORKLoginStep.json b/ResearchKitTests/samples.bundle/ORKLoginStep.json index 7683102687..0ae705e15e 100644 --- a/ResearchKitTests/samples.bundle/ORKLoginStep.json +++ b/ResearchKitTests/samples.bundle/ORKLoginStep.json @@ -1 +1 @@ -{"bodyItems":[],"detailText":"", "headerTextAlignment": 0, "loginViewControllerString":"ORKLoginStepViewController","optional":true,"useSurveyMode":true,"shouldTintImages":true,"_class":"ORKLoginStep","iconImage":{"imageName":"65159B22-6011-4EB7-81BD-2E597B4AA29A"},"auxiliaryImage":{"imageName":"45AA55E2-9A86-4285-9FF7-A1E77856C480"},"title":"","identifier":"","footnote":"","shouldAutomaticallyAdjustImageTintColor":0,"image":{"imageName":"5B301CC2-521C-4403-BFBA-7597E0A93CFA"},"text":"","formItems":[],"useCardView":true,"imageContentMode": 0,"footerText":"","bodyItemTextAlignment":0,"buildInBodyItems": 0,"cardViewStyle":0,"useExtendedPadding":0,"earlyTerminationConfiguration": {"_class": "ORKEarlyTerminationConfiguration"}} +{"bodyItems":[],"detailText":"", "headerTextAlignment": 0, "loginViewControllerString":"ORKLoginStepViewController","optional":true,"useSurveyMode":true,"shouldTintImages":true,"_class":"ORKLoginStep","iconImage":{"imageName":"65159B22-6011-4EB7-81BD-2E597B4AA29A"},"auxiliaryImage":{"imageName":"45AA55E2-9A86-4285-9FF7-A1E77856C480"},"title":"","identifier":"","footnote":"","shouldAutomaticallyAdjustImageTintColor":0,"image":{"imageName":"5B301CC2-521C-4403-BFBA-7597E0A93CFA"},"text":"","formItems":[],"useCardView":true,"autoScrollEnabled":true,"imageContentMode": 0,"footerText":"","bodyItemTextAlignment":0,"buildInBodyItems": 0,"cardViewStyle":0,"useExtendedPadding":0,"earlyTerminationConfiguration": {"_class": "ORKEarlyTerminationConfiguration"}} diff --git a/ResearchKitTests/samples.bundle/ORKRegistrationStep.json b/ResearchKitTests/samples.bundle/ORKRegistrationStep.json index 130087e01d..e709c2fb06 100644 --- a/ResearchKitTests/samples.bundle/ORKRegistrationStep.json +++ b/ResearchKitTests/samples.bundle/ORKRegistrationStep.json @@ -1 +1 @@ -{"bodyItems":[],"detailText":"", "headerTextAlignment": 0, "options":0,"optional":false,"useSurveyMode":true,"shouldTintImages":true,"_class":"ORKRegistrationStep","auxiliaryImage":{"imageName":"AE8E0687-1A0C-42C1-964A-E8F89E789B1E"},"iconImage":{"imageName":"4C7914C4-0EA8-4D43-A7B0-ECB2E3DE0FAC"},"title":"","identifier":"","footnote":"","shouldAutomaticallyAdjustImageTintColor":0,"image":{"imageName":"0BB5BA89-09CC-4DB0-B941-6A2D51834EC6"},"text":"","formItems":[],"useCardView":true,"imageContentMode": 0,"footerText":"","bodyItemTextAlignment":0,"buildInBodyItems": 0,"cardViewStyle":0,"useExtendedPadding":0,"earlyTerminationConfiguration": {"_class": "ORKEarlyTerminationConfiguration"}} +{"bodyItems":[],"detailText":"", "headerTextAlignment": 0, "options":0,"optional":false,"useSurveyMode":true,"shouldTintImages":true,"_class":"ORKRegistrationStep","auxiliaryImage":{"imageName":"AE8E0687-1A0C-42C1-964A-E8F89E789B1E"},"iconImage":{"imageName":"4C7914C4-0EA8-4D43-A7B0-ECB2E3DE0FAC"},"title":"","identifier":"","footnote":"","shouldAutomaticallyAdjustImageTintColor":0,"image":{"imageName":"0BB5BA89-09CC-4DB0-B941-6A2D51834EC6"},"text":"","formItems":[],"useCardView":true,"autoScrollEnabled":true,"imageContentMode": 0,"footerText":"","bodyItemTextAlignment":0,"buildInBodyItems": 0,"cardViewStyle":0,"useExtendedPadding":0,"earlyTerminationConfiguration": {"_class": "ORKEarlyTerminationConfiguration"}} diff --git a/ResearchKitTests/samples.bundle/ORKdBHLToneAudiometryOnboardingStep.json b/ResearchKitTests/samples.bundle/ORKdBHLToneAudiometryOnboardingStep.json index 03328b8ac3..86843bddcf 100644 --- a/ResearchKitTests/samples.bundle/ORKdBHLToneAudiometryOnboardingStep.json +++ b/ResearchKitTests/samples.bundle/ORKdBHLToneAudiometryOnboardingStep.json @@ -1 +1 @@ -{"bodyItems":[],"detailText":"", "headerTextAlignment": 0, "optional":true,"useSurveyMode":true,"shouldTintImages":true,"_class":"ORKdBHLToneAudiometryOnboardingStep","auxiliaryImage":{"imageName":"0255CA0B-11EA-4502-926A-07DCA0599AEC"},"iconImage":{"imageName":"B10BDAB3-6380-4F75-A5D3-7E334CD94C7D"},"title":"","identifier":"","footnote":"","shouldAutomaticallyAdjustImageTintColor":0,"image":{"imageName":"E2856DA0-1728-4A16-A468-9A940C0E6F95"},"text":"","formItems":[],"useCardView":true,"imageContentMode": 0,"footerText":"","bodyItemTextAlignment":0,"buildInBodyItems": 0,"cardViewStyle":0,"useExtendedPadding":0,"earlyTerminationConfiguration":{"_class":"ORKEarlyTerminationConfiguration"}} +{"bodyItems":[],"detailText":"", "headerTextAlignment": 0, "optional":true,"useSurveyMode":true,"shouldTintImages":true,"_class":"ORKdBHLToneAudiometryOnboardingStep","auxiliaryImage":{"imageName":"0255CA0B-11EA-4502-926A-07DCA0599AEC"},"iconImage":{"imageName":"B10BDAB3-6380-4F75-A5D3-7E334CD94C7D"},"title":"","identifier":"","footnote":"","shouldAutomaticallyAdjustImageTintColor":0,"image":{"imageName":"E2856DA0-1728-4A16-A468-9A940C0E6F95"},"text":"","formItems":[],"useCardView":true,"autoScrollEnabled":true,"imageContentMode": 0,"footerText":"","bodyItemTextAlignment":0,"buildInBodyItems": 0,"cardViewStyle":0,"useExtendedPadding":0,"earlyTerminationConfiguration":{"_class":"ORKEarlyTerminationConfiguration"}} diff --git a/ResearchKitUI/Accessibility/Localized/en.lproj/ResearchKitUI.strings b/ResearchKitUI/Accessibility/Localized/en.lproj/ResearchKitUI.strings new file mode 100644 index 0000000000..bd90420601 --- /dev/null +++ b/ResearchKitUI/Accessibility/Localized/en.lproj/ResearchKitUI.strings @@ -0,0 +1,31 @@ +/* + Copyright (c) 2020, 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. + */ + +"BUTTON_CANCEL" = "Cancel"; diff --git a/ResearchKitUI/Common/Answer Format/ORKSurveyCardHeaderView.h b/ResearchKitUI/Common/Answer Format/ORKSurveyCardHeaderView.h index 02445775b9..ce11019bc9 100644 --- a/ResearchKitUI/Common/Answer Format/ORKSurveyCardHeaderView.h +++ b/ResearchKitUI/Common/Answer Format/ORKSurveyCardHeaderView.h @@ -28,7 +28,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -@import UIKit; +#import NS_ASSUME_NONNULL_BEGIN @class ORKLearnMoreView; diff --git a/ResearchKitUI/Common/Answer Format/ORKSurveyCardHeaderView.m b/ResearchKitUI/Common/Answer Format/ORKSurveyCardHeaderView.m index 0f0970eef8..990043de31 100644 --- a/ResearchKitUI/Common/Answer Format/ORKSurveyCardHeaderView.m +++ b/ResearchKitUI/Common/Answer Format/ORKSurveyCardHeaderView.m @@ -46,7 +46,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE NSString * const ORKSurveyCardHeaderViewProgressLabelAccessibilityIdentifier = @"ORKSurveyCardHeaderView_progressLabel"; NSString * const ORKSurveyCardHeaderViewDetailTextLabelAccessibilityIdentifier = @"ORKSurveyCardHeaderView_detailTextLabel"; NSString * const ORKSurveyCardHeaderViewSelectAllThatApplyLabelAccessibilityIdentifier = @"ORKSurveyCardHeaderView_selectAllThatApplyLabel"; -NSString * const UITestLaunchArgument = @"UITest"; @implementation ORKSurveyCardHeaderView { diff --git a/ResearchKitUI/Common/Container Views/Learn More/ORKLearnMoreView.h b/ResearchKitUI/Common/Container Views/Learn More/ORKLearnMoreView.h index 360c1dd896..f38e8fc369 100644 --- a/ResearchKitUI/Common/Container Views/Learn More/ORKLearnMoreView.h +++ b/ResearchKitUI/Common/Container Views/Learn More/ORKLearnMoreView.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitUI/Common/Container Views/ORKBodyContainerView.h b/ResearchKitUI/Common/Container Views/ORKBodyContainerView.h index 405e903938..0b5dd23b52 100644 --- a/ResearchKitUI/Common/Container Views/ORKBodyContainerView.h +++ b/ResearchKitUI/Common/Container Views/ORKBodyContainerView.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitUI/Common/Container Views/ORKBodyContainerView.m b/ResearchKitUI/Common/Container Views/ORKBodyContainerView.m index a9934d54f8..3d48093eaa 100644 --- a/ResearchKitUI/Common/Container Views/ORKBodyContainerView.m +++ b/ResearchKitUI/Common/Container Views/ORKBodyContainerView.m @@ -299,7 +299,7 @@ - (void)setupBodyStyleBulletPointView { - (void)setupBodyStyleImage { UIImageView *imageView = [self imageView]; - self.alignment = UIStackViewAlignmentCenter; + self.alignment = _bodyItem.alignImageToTop ? UIStackViewAlignmentTop : UIStackViewAlignmentCenter; if (_bodyItem.useCardStyle == YES) { imageView.translatesAutoresizingMaskIntoConstraints = NO; diff --git a/ResearchKitUI/Common/Container Views/ORKNavigationContainerView.h b/ResearchKitUI/Common/Container Views/ORKNavigationContainerView.h index 3dda1458f4..83655422c9 100644 --- a/ResearchKitUI/Common/Container Views/ORKNavigationContainerView.h +++ b/ResearchKitUI/Common/Container Views/ORKNavigationContainerView.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import #import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitUI/Common/Container Views/ORKStepContentView.h b/ResearchKitUI/Common/Container Views/ORKStepContentView.h index 61b1160148..c4ff2627a8 100644 --- a/ResearchKitUI/Common/Container Views/ORKStepContentView.h +++ b/ResearchKitUI/Common/Container Views/ORKStepContentView.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitUI/Common/Container Views/ORKStepHeaderView.h b/ResearchKitUI/Common/Container Views/ORKStepHeaderView.h index c77db1959c..a27eea25f1 100644 --- a/ResearchKitUI/Common/Container Views/ORKStepHeaderView.h +++ b/ResearchKitUI/Common/Container Views/ORKStepHeaderView.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitUI/Common/Container Views/ORKTableContainerView.h b/ResearchKitUI/Common/Container Views/ORKTableContainerView.h index f226c13fc7..acd3fab0f7 100644 --- a/ResearchKitUI/Common/Container Views/ORKTableContainerView.h +++ b/ResearchKitUI/Common/Container Views/ORKTableContainerView.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import #import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitUI/Common/Container Views/ORKVerticalContainerView.h b/ResearchKitUI/Common/Container Views/ORKVerticalContainerView.h index d13993c97b..036d6fc023 100644 --- a/ResearchKitUI/Common/Container Views/ORKVerticalContainerView.h +++ b/ResearchKitUI/Common/Container Views/ORKVerticalContainerView.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitUI/Common/Container Views/ORKVerticalContainerView.m b/ResearchKitUI/Common/Container Views/ORKVerticalContainerView.m index e9f1e30840..d3c73309c1 100644 --- a/ResearchKitUI/Common/Container Views/ORKVerticalContainerView.m +++ b/ResearchKitUI/Common/Container Views/ORKVerticalContainerView.m @@ -32,7 +32,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKVerticalContainerView.h" #import "ORKVerticalContainerView_Internal.h" -#import "ORKCustomStepView_Internal.h" #import "ORKNavigationContainerView.h" #import "ORKStepHeaderView_Internal.h" #import "ORKTintedImageView.h" diff --git a/ResearchKitUI/Common/Ring View/ORKRingView.h b/ResearchKitUI/Common/Ring View/ORKRingView.h index f830124be2..b4e5f6eaf4 100644 --- a/ResearchKitUI/Common/Ring View/ORKRingView.h +++ b/ResearchKitUI/Common/Ring View/ORKRingView.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import #import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitUI/Common/Skin/ORKBorderedButton.h b/ResearchKitUI/Common/Skin/ORKBorderedButton.h index 6f7c6565dc..ea2c320215 100644 --- a/ResearchKitUI/Common/Skin/ORKBorderedButton.h +++ b/ResearchKitUI/Common/Skin/ORKBorderedButton.h @@ -47,12 +47,6 @@ typedef NS_ENUM(NSInteger, ORKBorderedButtonDisabledStyle) { ORK_CLASS_AVAILABLE -@interface CALayer (ORKCornerCurveContinuousCategory) - -- (void)setCornerCurveContinuous; -- (void)setCornerCurveCircular; - -@end @interface ORKBorderedButton : ORKTextButton diff --git a/ResearchKitUI/Common/Skin/ORKBorderedButton.m b/ResearchKitUI/Common/Skin/ORKBorderedButton.m index e7aa615892..5d5cc55903 100644 --- a/ResearchKitUI/Common/Skin/ORKBorderedButton.m +++ b/ResearchKitUI/Common/Skin/ORKBorderedButton.m @@ -30,6 +30,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKBorderedButton.h" +#import "ORKBorderedButton_Internal.h" #import "ORKTextButton_Internal.h" diff --git a/ResearchKitUI/Common/Skin/ORKBorderedButton_Internal.h b/ResearchKitUI/Common/Skin/ORKBorderedButton_Internal.h new file mode 100644 index 0000000000..439384bebe --- /dev/null +++ b/ResearchKitUI/Common/Skin/ORKBorderedButton_Internal.h @@ -0,0 +1,36 @@ +/* + Copyright (c) 2024, 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. + */ + +@interface CALayer (ORKCornerCurveContinuousCategory) + +- (void)setCornerCurveContinuous; +- (void)setCornerCurveCircular; + +@end diff --git a/ResearchKitUI/Common/Skin/ORKDirectionView.h b/ResearchKitUI/Common/Skin/ORKDirectionView.h index dfbebafe77..87e62067e4 100644 --- a/ResearchKitUI/Common/Skin/ORKDirectionView.h +++ b/ResearchKitUI/Common/Skin/ORKDirectionView.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import #import #import diff --git a/ResearchKitUI/Common/Skin/ORKDontKnowButton.m b/ResearchKitUI/Common/Skin/ORKDontKnowButton.m index b80961ff29..d1e3bd618d 100644 --- a/ResearchKitUI/Common/Skin/ORKDontKnowButton.m +++ b/ResearchKitUI/Common/Skin/ORKDontKnowButton.m @@ -31,6 +31,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKDontKnowButton.h" #import "ORKHelpers_Internal.h" #import "ORKBorderedButton.h" +#import "ORKBorderedButton_Internal.h" #import "ORKCheckmarkView.h" #import "ORKSkin.h" #import "ORKLabel.h" diff --git a/ResearchKitUI/Common/Skin/ORKIconButton.m b/ResearchKitUI/Common/Skin/ORKIconButton.m index 3d4d1fb468..5837080ac3 100644 --- a/ResearchKitUI/Common/Skin/ORKIconButton.m +++ b/ResearchKitUI/Common/Skin/ORKIconButton.m @@ -32,6 +32,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKHelpers_Internal.h" #import "ORKLabel.h" #import "ORKBorderedButton.h" +#import "ORKBorderedButton_Internal.h" @implementation ORKIconButton { UIView *_customView; diff --git a/ResearchKitUI/Common/Skin/ORKProgressView.h b/ResearchKitUI/Common/Skin/ORKProgressView.h index 4c3c82e3ba..a5139cb09b 100644 --- a/ResearchKitUI/Common/Skin/ORKProgressView.h +++ b/ResearchKitUI/Common/Skin/ORKProgressView.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import #import diff --git a/ResearchKitUI/Common/Skin/ORKRoundTappingButton.m b/ResearchKitUI/Common/Skin/ORKRoundTappingButton.m index 1f1a27b58a..93c134b0b6 100644 --- a/ResearchKitUI/Common/Skin/ORKRoundTappingButton.m +++ b/ResearchKitUI/Common/Skin/ORKRoundTappingButton.m @@ -30,6 +30,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKTextButton_Internal.h" #import "ORKRoundTappingButton.h" +#import "ORKBorderedButton_Internal.h" static const CGFloat RoundTappingButtonDefaultDiameter = 104; diff --git a/ResearchKitUI/Common/Skin/ORKSeparatorView.h b/ResearchKitUI/Common/Skin/ORKSeparatorView.h index c754fdfb6e..87e353c36b 100644 --- a/ResearchKitUI/Common/Skin/ORKSeparatorView.h +++ b/ResearchKitUI/Common/Skin/ORKSeparatorView.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import #import diff --git a/ResearchKitUI/Common/Skin/ORKTintedImageView.h b/ResearchKitUI/Common/Skin/ORKTintedImageView.h index 931d59f401..104b3d66b9 100644 --- a/ResearchKitUI/Common/Skin/ORKTintedImageView.h +++ b/ResearchKitUI/Common/Skin/ORKTintedImageView.h @@ -29,7 +29,7 @@ */ -@import UIKit; +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitUI/Common/Step/Custom Step/ORKCustomStepViewController.m b/ResearchKitUI/Common/Step/Custom Step/ORKCustomStepViewController.m index b5cac35ff3..27c726488b 100644 --- a/ResearchKitUI/Common/Step/Custom Step/ORKCustomStepViewController.m +++ b/ResearchKitUI/Common/Step/Custom Step/ORKCustomStepViewController.m @@ -36,6 +36,8 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKStepContainerView_Private.h" #import "ORKStepView_Private.h" +NSString * const ORKCustomStepViewAccessibilityIdentifier = @"ORKCustomStepView"; + @interface ORKCustomStepViewController () @end @@ -65,6 +67,7 @@ - (void)stepDidChange { if (self.step && [self isViewLoaded]) { _containerView = [[ORKStepContainerView alloc] init]; + _containerView.accessibilityIdentifier = ORKCustomStepViewAccessibilityIdentifier; [self configureContainerView]; [_containerView setPinNavigationContainer:self.customStep.pinNavigationContainer]; [_containerView setCustomContentView:[self customStep].contentView withTopPadding:0.0 sidePadding:0.0]; diff --git a/ResearchKitUI/Common/Step/Form Step/ORKFormStepViewController.m b/ResearchKitUI/Common/Step/Form Step/ORKFormStepViewController.m index 6bd11b314e..829f1f3731 100644 --- a/ResearchKitUI/Common/Step/Form Step/ORKFormStepViewController.m +++ b/ResearchKitUI/Common/Step/Form Step/ORKFormStepViewController.m @@ -1337,6 +1337,10 @@ - (NSInteger)maxLabelWidth { // Return NO if we didn't autoscroll - (BOOL)didAutoScrollToNextItem:(ORKFormItemCell *)cell { + if (![self _isAutoScrollEnabled]) { + return NO; + } + NSIndexPath *currentIndexPath = [self.tableView indexPathForCell:cell]; if (cell.isLastItem) { @@ -1357,6 +1361,10 @@ - (BOOL)didAutoScrollToNextItem:(ORKFormItemCell *)cell { } - (BOOL)shouldAutoScrollToNextSection:(NSIndexPath *)indexPath { + if (![self _isAutoScrollEnabled]) { + return NO; + } + BOOL result = YES; NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:0 inSection:(indexPath.section + 1)]; @@ -1383,6 +1391,10 @@ - (BOOL)shouldAutoScrollToNextSection:(NSIndexPath *)indexPath { } - (void)autoScrollToNextSection:(NSIndexPath *)indexPath { + if (![self _isAutoScrollEnabled]) { + return; + } + NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:0 inSection:(indexPath.section + 1)]; UITableView *tableView = self.tableView; UITableViewCell *nextCell = [tableView cellForRowAtIndexPath:nextIndexPath]; @@ -1399,16 +1411,28 @@ - (void)autoScrollToNextSection:(NSIndexPath *)indexPath { } - (void)scrollToFirstUnansweredSection { + if (![self _isAutoScrollEnabled]) { + return; + } + ORKFormItem *formItem = [self fetchFirstUnansweredNonOptionalFormItem:[self answerableFormItems]]; [self scrollToFormItem:formItem]; } - (void)scrollToFooter { + if (![self _isAutoScrollEnabled]) { + return; + } + CGRect tableFooterRect = [self.tableView convertRect:self.tableView.tableFooterView.bounds fromView:self.tableView.tableFooterView]; [self.tableView scrollRectToVisible:tableFooterRect animated:YES]; } - (void)scrollToFormItem:(ORKFormItem *)formItem { + if (![self _isAutoScrollEnabled]) { + return; + } + NSString *sectionIdentifier = [self fetchSectionThatContainsFormItem:formItem]; NSInteger section = [[_diffableDataSource snapshot] indexOfSectionIdentifier:sectionIdentifier]; if (section != NSNotFound) { @@ -1419,6 +1443,11 @@ - (void)scrollToFormItem:(ORKFormItem *)formItem { } } +- (BOOL)_isAutoScrollEnabled { + ORKFormStep *formStep = [self formStep]; + return formStep.autoScrollEnabled; +} + - (nullable ORKTextChoiceAnswerFormat *)textChoiceAnswerFormatForIndexPath:(NSIndexPath *)indexPath { ORKTextChoiceAnswerFormat *result = nil; @@ -1705,9 +1734,11 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath ORKFormItemCell *formItemCell = ORKDynamicCast(cell, ORKFormItemCell); if (formItemCell != nil) { [formItemCell becomeFirstResponder]; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, DelayBeforeAutoScroll * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - [_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; - }); + if ([self _isAutoScrollEnabled]) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, DelayBeforeAutoScroll * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ + [_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; + }); + } } ORKTextChoiceAnswerFormat *textChoiceAnswerFormat = ORKDynamicCast(formItem.impliedAnswerFormat, ORKTextChoiceAnswerFormat); @@ -1979,7 +2010,9 @@ - (void)finishHandlingFormItemCellDidResignFirstResponder:(ORKTableCellItemIdent [formItemCell becomeFirstResponder]; } - [_tableView scrollToRowAtIndexPath:nextPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; + if ([self _isAutoScrollEnabled]) { + [_tableView scrollToRowAtIndexPath:nextPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; + } } }); } @@ -2040,12 +2073,13 @@ - (void)encodeRestorableStateWithCoder:(NSCoder *)coder { - (void)decodeRestorableStateWithCoder:(NSCoder *)coder { [super decodeRestorableStateWithCoder:coder]; - _savedAnswers = [coder decodeObjectOfClass:[NSMutableDictionary class] forKey:_ORKSavedAnswersRestoreKey]; - _savedAnswerDates = [coder decodeObjectOfClass:[NSMutableDictionary class] forKey:_ORKSavedAnswerDatesRestoreKey]; - _savedSystemCalendars = [coder decodeObjectOfClass:[NSMutableDictionary class] forKey:_ORKSavedSystemCalendarsRestoreKey]; - _savedSystemTimeZones = [coder decodeObjectOfClass:[NSMutableDictionary class] forKey:_ORKSavedSystemTimeZonesRestoreKey]; - _originalAnswers = [coder decodeObjectOfClass:[NSMutableDictionary class] forKey:_ORKOriginalAnswersRestoreKey]; - _identifiersOfAnsweredSections = [coder decodeObjectOfClass:[NSMutableSet class] forKey:_ORKAnsweredSectionIdentifiersRestoreKey]; + NSSet *decodableAnswerTypes = [NSSet setWithObjects:NSMutableDictionary.self, NSString.self, NSNumber.self, NSDate.self, nil]; + _savedAnswers = [coder decodeObjectOfClasses:decodableAnswerTypes forKey:_ORKSavedAnswersRestoreKey]; + _savedAnswerDates = [coder decodeObjectOfClasses:[NSSet setWithArray:@[NSMutableDictionary.self, NSString.self, NSDate.self]] forKey:_ORKSavedAnswerDatesRestoreKey]; + _savedSystemCalendars = [coder decodeObjectOfClasses:[NSSet setWithArray:@[NSMutableDictionary.self, NSString.self, NSCalendar.self]] forKey:_ORKSavedSystemCalendarsRestoreKey]; + _savedSystemTimeZones = [coder decodeObjectOfClasses:[NSSet setWithArray:@[NSMutableDictionary.self, NSString.self, NSTimeZone.self]] forKey:_ORKSavedSystemTimeZonesRestoreKey]; + _originalAnswers = [coder decodeObjectOfClasses:decodableAnswerTypes forKey:_ORKOriginalAnswersRestoreKey]; + _identifiersOfAnsweredSections = [coder decodeObjectOfClasses:[NSSet setWithArray:@[NSMutableSet.self, NSString.self]] forKey:_ORKAnsweredSectionIdentifiersRestoreKey]; } #pragma mark Rotate diff --git a/ResearchKitUI/Common/Step/Instruction Step/Completion Step/ORKCompletionStepViewController.m b/ResearchKitUI/Common/Step/Instruction Step/Completion Step/ORKCompletionStepViewController.m index fb0a5c5168..70d734c4a0 100644 --- a/ResearchKitUI/Common/Step/Instruction Step/Completion Step/ORKCompletionStepViewController.m +++ b/ResearchKitUI/Common/Step/Instruction Step/Completion Step/ORKCompletionStepViewController.m @@ -31,7 +31,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKCompletionStepViewController.h" -#import "ORKCustomStepView_Internal.h" #import "ORKInstructionStepContainerView.h" #import "ORKNavigationContainerView.h" #import "ORKStepHeaderView_Internal.h" diff --git a/ResearchKitUI/Common/Step/Instruction Step/LearnMore Step/ORKLearnMoreStepViewController.m b/ResearchKitUI/Common/Step/Instruction Step/LearnMore Step/ORKLearnMoreStepViewController.m index 0f99012f83..718542d6b8 100644 --- a/ResearchKitUI/Common/Step/Instruction Step/LearnMore Step/ORKLearnMoreStepViewController.m +++ b/ResearchKitUI/Common/Step/Instruction Step/LearnMore Step/ORKLearnMoreStepViewController.m @@ -38,11 +38,16 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE static const CGFloat ORKScrollViewCustomContentInset = 40.0; +NSString * const ORKLearnMoreStepViewAccessibilityIdentifier = @"ORKLearnMoreStepView"; +NSString * const ORKLearnMoreViewDoneButtonAccessibilityIdentifier = @"ORKLearnMoreStepViewDoneButton"; + @implementation ORKLearnMoreStepViewController - (void)stepDidChange { [super stepDidChange]; [self.stepView.navigationFooterView setHidden:YES]; + + self.stepView.accessibilityIdentifier = ORKLearnMoreStepViewAccessibilityIdentifier; } - (void)viewWillAppear:(BOOL)animated { @@ -59,6 +64,7 @@ - (void)viewWillAppear:(BOOL)animated { self.navigationController.navigationBar.shadowImage = [UIImage new]; self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:ORKLocalizedString(@"BUTTON_DONE", nil) style:UIBarButtonItemStyleDone target:self action:@selector(doneButtonPressed:)]; + self.navigationItem.rightBarButtonItem.accessibilityIdentifier = ORKLearnMoreViewDoneButtonAccessibilityIdentifier; if (self.stepView.navigationFooterView.isHidden) { [self.stepView setScrollViewCustomContentInset: ORKScrollViewCustomContentInset]; diff --git a/ResearchKitUI/Common/Step/ORKCustomStepView.m b/ResearchKitUI/Common/Step/ORKCustomStepView.m index b85d879575..f3b3efde63 100644 --- a/ResearchKitUI/Common/Step/ORKCustomStepView.m +++ b/ResearchKitUI/Common/Step/ORKCustomStepView.m @@ -30,7 +30,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKCustomStepView.h" -#import "ORKCustomStepView_Internal.h" #import "ORKSurveyAnswerCell.h" #import "ORKSurveyCardHeaderView.h" @@ -40,29 +39,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKSkin.h" -@implementation ORKActiveStepCustomView - -- (void)resetStep:(ORKStepViewController *)viewController { -} - -- (void)startStep:(ORKStepViewController *)viewController { -} - -- (void)suspendStep:(ORKStepViewController *)viewController { -} - -- (void)resumeStep:(ORKStepViewController *)viewController { -} - -- (void)finishStep:(ORKStepViewController *)viewController { -} - -- (void)updateDisplay:(ORKActiveStepViewController *)viewController { -} - -@end - - @implementation ORKQuestionStepCustomView @end diff --git a/ResearchKitUI/Common/Step/ORKStepViewController.m b/ResearchKitUI/Common/Step/ORKStepViewController.m index 4f0ca8e8e5..ab652027c9 100644 --- a/ResearchKitUI/Common/Step/ORKStepViewController.m +++ b/ResearchKitUI/Common/Step/ORKStepViewController.m @@ -616,7 +616,7 @@ - (void)decodeRestorableStateWithCoder:(NSCoder *)coder { self.parentReviewStep = [coder decodeObjectOfClass:[ORKReviewStep class] forKey:_ORKParentReviewStepKey]; - _addedResults = [coder decodeObjectOfClass:[NSArray class] forKey:_ORKAddedResultsKey]; + _addedResults = [coder decodeObjectOfClasses:[NSSet setWithArray:@[NSArray.self, ORKResult.self]] forKey:_ORKAddedResultsKey]; } + (UIViewController *)viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder { diff --git a/ResearchKitUI/Common/Step/ORKStepView_Private.h b/ResearchKitUI/Common/Step/ORKStepView_Private.h index 74237f6611..d69faa50a3 100644 --- a/ResearchKitUI/Common/Step/ORKStepView_Private.h +++ b/ResearchKitUI/Common/Step/ORKStepView_Private.h @@ -28,7 +28,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -@import UIKit; +#import #import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitUI/Common/Step/PDFStep/ORKFreehandDrawingView.h b/ResearchKitUI/Common/Step/PDFStep/ORKFreehandDrawingView.h index 08f53ce88c..66bdcc0a2b 100644 --- a/ResearchKitUI/Common/Step/PDFStep/ORKFreehandDrawingView.h +++ b/ResearchKitUI/Common/Step/PDFStep/ORKFreehandDrawingView.h @@ -30,8 +30,8 @@ */ -@import UIKit; -@import PDFKit; +#import +#import #import diff --git a/ResearchKitUI/Common/Step/PDFStep/ORKPDFViewerStepView.h b/ResearchKitUI/Common/Step/PDFStep/ORKPDFViewerStepView.h index c6d54c76e9..a89547c035 100644 --- a/ResearchKitUI/Common/Step/PDFStep/ORKPDFViewerStepView.h +++ b/ResearchKitUI/Common/Step/PDFStep/ORKPDFViewerStepView.h @@ -28,7 +28,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "ORKCustomStepView_Internal.h" @import PDFKit; diff --git a/ResearchKitUI/Common/Step/PDFStep/ORKPDFViewerStepView.m b/ResearchKitUI/Common/Step/PDFStep/ORKPDFViewerStepView.m index 105b2351f6..245e29b87f 100644 --- a/ResearchKitUI/Common/Step/PDFStep/ORKPDFViewerStepView.m +++ b/ResearchKitUI/Common/Step/PDFStep/ORKPDFViewerStepView.m @@ -45,6 +45,16 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE const CGFloat PDFhideViewAnimationDuration = 0.5; +NSString * const ORKPDFViewerStepShowPDFThumbnailActionButtonAccessibilityIdentifier = @"ORKPDFViewerStep_showPDF_thumbnailActionButton"; +NSString * const ORKPDFViewerStepHidePDFThumbnailActionButtonAccessibilityIdentifier = @"ORKPDFViewerStep_hidePDF_thumbnailActionButton"; +NSString * const ORKPDFViewerStepAnnotationActionButtonAccessibilityIdentifier = @"ORKPDFViewerStep_annotationActionButton"; +NSString * const ORKPDFViewerStepShowSearchActionButtonAccessibilityIdentifier = @"ORKPDFViewerStep_showSearchActionButton"; +NSString * const ORKPDFViewerStepHideSearchActionButtonAccessibilityIdentifier = @"ORKPDFViewerStep_hideSearchActionButton"; +NSString * const ORKPDFViewerStepShareActionButtonAccessibilityIdentifier = @"ORKPDFViewerStep_shareActionButton"; +NSString * const ORKPDFViewerActionViewExitButtonAccessibilityIdentifier = @"ORKPDFViewerActionView_exitButton"; +NSString * const ORKPDFViewerActionViewApplyButtonAccessibilityIdentifier = @"ORKPDFViewerActionView_applyButton"; +NSString * const ORKPDFViewerActionViewClearButtonAccessibilityIdentifier = @"ORKPDFViewerActionView_clearButton"; + @interface ORKPDFViewerActionsView: UIView @property (nonatomic, nonnull) UIView *thumbnailActionView; @@ -165,6 +175,7 @@ - (void)setupClearAnnotationsButton { _clearAnnotationsButton.translatesAutoresizingMaskIntoConstraints = NO; _clearButtonView = [UIView new]; _clearButtonView.translatesAutoresizingMaskIntoConstraints = NO; + _clearButtonView.accessibilityIdentifier = ORKPDFViewerActionViewClearButtonAccessibilityIdentifier; [_clearAnnotationsButton setTitle:ORKLocalizedString(@"BUTTON_CLEAR", nil) forState:UIControlStateNormal]; [_clearButtonView addSubview:_clearAnnotationsButton]; [_stackView addArrangedSubview:_clearButtonView]; @@ -201,6 +212,7 @@ - (void)setupApplyAnnotationsButton { _applyAnnotationsButton.translatesAutoresizingMaskIntoConstraints = NO; _applyButtonView = [UIView new]; _applyButtonView.translatesAutoresizingMaskIntoConstraints = NO; + _applyButtonView.accessibilityIdentifier = ORKPDFViewerActionViewApplyButtonAccessibilityIdentifier; [_applyAnnotationsButton setTitle:ORKLocalizedString(@"BUTTON_APPLY", nil) forState:UIControlStateNormal]; [_applyButtonView addSubview:_applyAnnotationsButton]; [_stackView addArrangedSubview:_applyButtonView]; @@ -238,6 +250,7 @@ - (void)setupExitAnnotationsButton { _exitAnnotationsButton.translatesAutoresizingMaskIntoConstraints = NO; _exitButtonView = [UIView new]; _exitButtonView.translatesAutoresizingMaskIntoConstraints = NO; + _exitButtonView.accessibilityIdentifier = ORKPDFViewerActionViewExitButtonAccessibilityIdentifier; [_exitButtonView addSubview:_exitAnnotationsButton]; [_stackView addArrangedSubview:_exitButtonView]; [self activateConstraintsForButton:_exitAnnotationsButton withView:_exitButtonView]; @@ -521,6 +534,11 @@ - (void)updateActionButtonAccessibilityLabels { _pdfActionsView.annotationActionButton.accessibilityLabel = ORKLocalizedString(@"AX_BUTTON_ANNOTATE" , nil); _pdfActionsView.searchActionButton.accessibilityLabel = _searchBar.isHidden ? ORKLocalizedString(@"AX_BUTTON_SHOW_SEARCH", nil) : ORKLocalizedString(@"AX_BUTTON_HIDE_SEARCH", nil); _pdfActionsView.shareActionButton.accessibilityLabel = ORKLocalizedString(@"AX_BUTTON_SHARE", nil); + + _pdfActionsView.thumbnailActionButton.accessibilityIdentifier = _pdfThumbnailView.isHidden ?ORKPDFViewerStepShowPDFThumbnailActionButtonAccessibilityIdentifier : ORKPDFViewerStepHidePDFThumbnailActionButtonAccessibilityIdentifier; + _pdfActionsView.annotationActionButton.accessibilityIdentifier = ORKPDFViewerStepAnnotationActionButtonAccessibilityIdentifier; + _pdfActionsView.searchActionButton.accessibilityIdentifier = _searchBar.isHidden ? ORKPDFViewerStepShowSearchActionButtonAccessibilityIdentifier : ORKPDFViewerStepHideSearchActionButtonAccessibilityIdentifier; + _pdfActionsView.shareActionButton.accessibilityIdentifier = ORKPDFViewerStepShareActionButtonAccessibilityIdentifier; } - (void)shareButtonAction { diff --git a/ResearchKitUI/Common/Step/PDFStep/ORKPDFViewerStepViewController.m b/ResearchKitUI/Common/Step/PDFStep/ORKPDFViewerStepViewController.m index 88e2620023..2b9321e367 100644 --- a/ResearchKitUI/Common/Step/PDFStep/ORKPDFViewerStepViewController.m +++ b/ResearchKitUI/Common/Step/PDFStep/ORKPDFViewerStepViewController.m @@ -43,6 +43,8 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKHelpers_Internal.h" #import "ORKSkin.h" +NSString * const ORKPDFViewerStepViewAccessibilityIdentifier = @"ORKPDFViewerStepView"; + @interface ORKPDFViewerStepViewController() @end @@ -68,6 +70,7 @@ - (void)stepDidChange { _pdfView = [ORKPDFViewerStepView new]; [self hidePDFViewerButtons]; _pdfView.delegate = self; + _pdfView.accessibilityIdentifier = ORKPDFViewerStepViewAccessibilityIdentifier; [self.view addSubview:_pdfView]; [self setNavigationFooterView]; [self setupConstraints]; diff --git a/ResearchKitUI/Common/Step/Passcode Step/ORKPasscodeStepViewController.m b/ResearchKitUI/Common/Step/Passcode Step/ORKPasscodeStepViewController.m index 63747f4728..91cfab7260 100644 --- a/ResearchKitUI/Common/Step/Passcode Step/ORKPasscodeStepViewController.m +++ b/ResearchKitUI/Common/Step/Passcode Step/ORKPasscodeStepViewController.m @@ -57,6 +57,8 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE static CGFloat const kForgotPasscodeHorizontalPadding = 30.0f; static CGFloat const kForgotPasscodeHeight = 100.0f; +NSString * const ORKPasscodeStepViewAccessibilityIdentifier = @"ORKPasscodeStepView"; + @implementation ORKPasscodeStepViewController { ORKPasscodeStepView *_passcodeStepView; CGFloat _originalForgotPasscodeY; @@ -103,6 +105,7 @@ - (void)stepDidChange { _passcodeStepView = [ORKPasscodeStepView new]; _passcodeStepView.stepText = [self passcodeStep].text; _passcodeStepView.textField.delegate = self; + _passcodeStepView.accessibilityIdentifier = ORKPasscodeStepViewAccessibilityIdentifier; [_passcodeStepView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showHideKeyboard)]]; diff --git a/ResearchKitUI/Common/Step/Signature Step/ORKCustomSignatureFooterView.m b/ResearchKitUI/Common/Step/Signature Step/ORKCustomSignatureFooterView.m index a82ff36d6a..306ea6d58d 100644 --- a/ResearchKitUI/Common/Step/Signature Step/ORKCustomSignatureFooterView.m +++ b/ResearchKitUI/Common/Step/Signature Step/ORKCustomSignatureFooterView.m @@ -37,6 +37,8 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKResult_Private.h" static const CGFloat ORKSignatureToClearPadding = 15.0; +NSString * const SignatureViewAccessibilityIdentifier = @"ORKSignatureView"; +NSString * const ORKSignatureViewClearButtonAccessibilityIdentifier = @"ORKSignatureViewClearButton"; @implementation ORKCustomSignatureFooterView { NSMutableArray *_constraints; @@ -57,6 +59,7 @@ - (instancetype)init { - (void)configure { if (!_signatureView) { _signatureView = [[ORKSignatureView alloc] initWithoutDefaultWidth]; + _signatureView.accessibilityIdentifier = SignatureViewAccessibilityIdentifier; [self addSubview:_signatureView]; } @@ -65,6 +68,7 @@ - (void)configure { [_clearButton.titleLabel setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]]; [_clearButton setTitle:ORKLocalizedString(@"BUTTON_CLEAR_SIGNATURE", nil) forState:UIControlStateNormal]; [_clearButton addTarget:self action:@selector(clear) forControlEvents:UIControlEventTouchUpInside]; + _clearButton.accessibilityIdentifier = ORKSignatureViewClearButtonAccessibilityIdentifier; [self addSubview:_clearButton]; } diff --git a/ResearchKitUI/Common/Step/Wait Step/ORKWaitStepViewController.m b/ResearchKitUI/Common/Step/Wait Step/ORKWaitStepViewController.m index f6767efe92..a61e4e8a50 100644 --- a/ResearchKitUI/Common/Step/Wait Step/ORKWaitStepViewController.m +++ b/ResearchKitUI/Common/Step/Wait Step/ORKWaitStepViewController.m @@ -50,6 +50,8 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKHelpers_Internal.h" +NSString * const ORKWaitStepViewAccessibilityIdentifier = @"ORKWaitStepView"; + @implementation ORKWaitStepViewController { ORKWaitStepView *_waitStepView; @@ -87,6 +89,7 @@ - (void)stepDidChange { _waitStepView.stepHeaderTextAlignment = self.step.headerTextAlignment; _waitStepView.bodyItems = self.step.bodyItems; _waitStepView.stepTopContentImageContentMode = self.step.imageContentMode; + _waitStepView.accessibilityIdentifier = ORKWaitStepViewAccessibilityIdentifier; [self.taskViewController setNavigationBarColor:[self.view backgroundColor]]; } diff --git a/ResearchKitUI/Common/Task/ORKTaskViewController.h b/ResearchKitUI/Common/Task/ORKTaskViewController.h index 6218d03727..99b4416aee 100644 --- a/ResearchKitUI/Common/Task/ORKTaskViewController.h +++ b/ResearchKitUI/Common/Task/ORKTaskViewController.h @@ -361,7 +361,7 @@ ORK_CLASS_AVAILABLE @return A new task view controller. */ -- (instancetype)initWithTask:(id)task restorationData:(NSData *)data delegate:(id)delegate error:(NSError* __autoreleasing *)errorOut; +- (instancetype)initWithTask:(id)task restorationData:(NSData *)data delegate:(id)delegate error:(NSError* __autoreleasing *)errorOut NS_DESIGNATED_INITIALIZER; /** Creates a new task view controller that starts the task at the step that has the specified step identifier. @@ -381,6 +381,26 @@ ORK_CLASS_AVAILABLE defaultResultSource:(nullable id)defaultResultSource delegate:(id)delegate NS_DESIGNATED_INITIALIZER; +/** + Creates a new task view controller that starts the task at the step that has the specified step identifier. + + Call this method to start a task from a specific step. Additionally, you can supply a defaultResultSource to resume a + partially completed task, or to provide your own prefilled results. + + @param task The task to be presented. + @param ongoingResult An optional task result from a previous run of the task. If you provide an ongoingResult, the task will start at the step corresponding to the last result. + @param restoreAtFirstStep A boolean that determines if the restored task starts from the last or first step. + @param defaultResultSource A source that the task view controller can consult to obtain default answers for questions provided in question steps and form steps. + @param delegate The delegate for the task view controller. + + @return A new task view controller. + */ +- (instancetype)initWithTask:(id)task + ongoingResult:(nullable ORKTaskResult *)ongoingResult + restoreAtFirstStep:(BOOL)restoreAtFirstStep + defaultResultSource:(nullable id)defaultResultSource + delegate:(id)delegate; + /** The delegate for the task view controller. diff --git a/ResearchKitUI/Common/Task/ORKTaskViewController.m b/ResearchKitUI/Common/Task/ORKTaskViewController.m index 5cd3663de9..2475d87188 100644 --- a/ResearchKitUI/Common/Task/ORKTaskViewController.m +++ b/ResearchKitUI/Common/Task/ORKTaskViewController.m @@ -31,7 +31,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKTaskViewController.h" -#import "ORKActiveStepViewController.h" +#import "ORKBorderedButton.h" #import "ORKInstructionStepViewController_Internal.h" #import "ORKFormStepViewController.h" #import "ORKReviewStepViewController_Internal.h" @@ -48,13 +48,11 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKResult_Private.h" #import "ORKReviewStep_Internal.h" #import "ORKStep_Private.h" -#import "ORKTappingIntervalStep.h" #import "ORKViewControllerProviding.h" #import "ORKHelpers_Internal.h" #import "ORKObserver.h" #import "ORKSkin.h" -#import "ORKBorderedButton.h" #import "ORKTaskReviewViewController.h" #import @@ -242,7 +240,7 @@ - (instancetype)initWithTask:(id)task taskRunUUID:(NSUUID *)taskRunUUID } - (instancetype)initWithTask:(id)task restorationData:(NSData *)data delegate:(id)delegate error:(NSError* __autoreleasing *)errorOut { - self = [[self initWithNibName:nil bundle:nil] commonInitWithTask:task taskRunUUID:nil]; + self = [[super initWithNibName:nil bundle:nil] commonInitWithTask:task taskRunUUID:nil]; if (self) { self.delegate = delegate; @@ -250,6 +248,7 @@ - (instancetype)initWithTask:(id)task restorationData:(NSData *)data de self.restorationClass = [self class]; NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:errorOut]; [self decodeRestorableStateWithCoder:unarchiver]; + [unarchiver finishDecoding]; [self applicationFinishedRestoringState]; if (unarchiver == nil && errorOut != nil) { @@ -284,6 +283,21 @@ - (instancetype)initWithTask:(id)task return self; } +- (instancetype)initWithTask:(id)task + ongoingResult:(ORKTaskResult *)ongoingResult + restoreAtFirstStep:(BOOL)restoreAtFirstStep + defaultResultSource:(id)defaultResultSource + delegate:(id)delegate { + self = [self initWithTask:task ongoingResult:ongoingResult defaultResultSource:defaultResultSource delegate:delegate]; + + if (self) { + if (restoreAtFirstStep && ongoingResult != nil) { + _restoredStepIdentifier = ongoingResult.results.firstObject.identifier; + } + } + return self; +} + - (void)setTaskRunUUID:(NSUUID *)taskRunUUID { if (_hasBeenPresented) { @throw [NSException exceptionWithName:NSGenericException reason:@"Cannot change task instance UUID after presenting task controller" userInfo:nil]; @@ -973,9 +987,6 @@ - (void)showStepViewController:(ORKStepViewController *)stepViewController goFor stepViewController = lastStepViewController; _currentStepViewController = lastStepViewController; } - - UIColor *tintColor = ORKViewTintColor(self.view); - stepViewController.view.tintColor = tintColor; [newViewControllers addObject:stepViewController]; @@ -1578,7 +1589,14 @@ - (void)encodeRestorableStateWithCoder:(NSCoder *)coder { - (void)decodeRestorableStateWithCoder:(NSCoder *)coder { [super decodeRestorableStateWithCoder:coder]; - _taskRunUUID = [coder decodeObjectOfClass:[NSUUID class] forKey:_ORKTaskRunUUIDRestoreKey]; + NSUUID *decodedTaskRunUUID = [coder decodeObjectOfClass:[NSUUID class] forKey:_ORKTaskRunUUIDRestoreKey]; + if (decodedTaskRunUUID != nil) { + _taskRunUUID = decodedTaskRunUUID; + } else { + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:[NSString stringWithFormat:@"Restored task data taskRunUUID was nil"] + userInfo:nil]; + } self.showsProgressInNavigationBar = [coder decodeBoolForKey:_ORKShowsProgressInNavigationBarRestoreKey]; self.discardable = [coder decodeBoolForKey:_ORKDiscardableTaskRestoreKey]; self.progressMode = [coder decodeIntegerForKey:_ORKProgressMode]; @@ -1588,10 +1606,8 @@ - (void)decodeRestorableStateWithCoder:(NSCoder *)coder { // Must have a task object already provided by this point in the restoration, in order to restore any other state. if (_task) { - - // Recover partially entered results, even if we may not be able to jump to the desired step. - _managedResults = [coder decodeObjectOfClass:[NSMutableDictionary class] forKey:_ORKManagedResultsRestoreKey]; - _managedStepIdentifiers = [coder decodeObjectOfClass:[NSMutableArray class] forKey:_ORKManagedStepIdentifiersRestoreKey]; + _managedResults = [coder decodeObjectOfClasses:[NSSet setWithArray:@[NSMutableDictionary.self, NSString.self, ORKResult.self, ORKStepResult.self]] forKey:_ORKManagedResultsRestoreKey]; + _managedStepIdentifiers = [coder decodeObjectOfClasses:[NSSet setWithArray:@[NSMutableArray.self, NSString.self]] forKey:_ORKManagedStepIdentifiersRestoreKey]; _restoredTaskIdentifier = [coder decodeObjectOfClass:[NSString class] forKey:_ORKTaskIdentifierRestoreKey]; if (_restoredTaskIdentifier) { @@ -1603,11 +1619,10 @@ - (void)decodeRestorableStateWithCoder:(NSCoder *)coder { } if ([_task respondsToSelector:@selector(stepWithIdentifier:)]) { - _requestedHealthTypesForRead = [coder decodeObjectOfClass:[NSSet class] forKey:_ORKRequestedHealthTypesForReadRestoreKey]; - _requestedHealthTypesForWrite = [coder decodeObjectOfClass:[NSSet class] forKey:_ORKRequestedHealthTypesForWriteRestoreKey]; + _requestedHealthTypesForRead = [coder decodeObjectOfClasses:[NSSet setWithArray:@[NSSet.self, HKObjectType.self]] forKey:_ORKRequestedHealthTypesForReadRestoreKey]; + _requestedHealthTypesForWrite = [coder decodeObjectOfClasses:[NSSet setWithArray:@[NSSet.self, HKObjectType.self]] forKey:_ORKRequestedHealthTypesForWriteRestoreKey]; _presentedDate = [coder decodeObjectOfClass:[NSDate class] forKey:_ORKPresentedDate]; _lastBeginningInstructionStepIdentifier = [coder decodeObjectOfClass:[NSString class] forKey:_ORKLastBeginningInstructionStepIdentifierKey]; - _restoredStepIdentifier = [coder decodeObjectOfClass:[NSString class] forKey:_ORKStepIdentifierRestoreKey]; } else { ORK_Log_Info("Not restoring current step of task %@ because it does not implement -stepWithIdentifier:", _task.identifier); diff --git a/ResearchKitUI/Common/Task/ORKTaskViewController_Internal.h b/ResearchKitUI/Common/Task/ORKTaskViewController_Internal.h index 5d2d4a0ca5..e9fe513408 100644 --- a/ResearchKitUI/Common/Task/ORKTaskViewController_Internal.h +++ b/ResearchKitUI/Common/Task/ORKTaskViewController_Internal.h @@ -31,8 +31,7 @@ #import #import -#import -@import HealthKit; +#import NS_ASSUME_NONNULL_BEGIN diff --git a/ResearchKitUI/Info-iOS.plist b/ResearchKitUI/Info-iOS.plist index 8f81b40896..a495e5e6bb 100644 --- a/ResearchKitUI/Info-iOS.plist +++ b/ResearchKitUI/Info-iOS.plist @@ -19,6 +19,6 @@ CFBundleShortVersionString 1.0 CFBundleVersion - $(CURRENT_PROJECT_VERSION) + $(ORK_FRAMEWORK_BUILD_NUMBER) diff --git a/ResearchKitUI/Onboarding/Account/ORKVerificationStepViewController.m b/ResearchKitUI/Onboarding/Account/ORKVerificationStepViewController.m index 29e35fdc59..ab3263b840 100644 --- a/ResearchKitUI/Onboarding/Account/ORKVerificationStepViewController.m +++ b/ResearchKitUI/Onboarding/Account/ORKVerificationStepViewController.m @@ -41,6 +41,9 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #import "ORKHelpers_Internal.h" #import "ORKSkin.h" +NSString * const ORKVerificationStepViewAccessibilityIdentifier = @"ORKVerificationStepView"; +NSString * const ORKVerificationStepViewResendEmailButtonAccessibilityIdentifier = @"ORKVerificationStepViewResendEmailButton"; + @implementation ORKVerificationStepViewController { ORKVerificationStepView *_verificationStepView; NSArray *_constraints; @@ -59,6 +62,7 @@ - (void)stepDidChange { _verificationStepView = [ORKVerificationStepView new]; _verificationStepView.headerView.instructionLabel.text = [[self verificationStep].text stringByAppendingString:[NSString stringWithFormat:@"\n\n%@", ORKLocalizedString(@"RESEND_EMAIL_LABEL_MESSAGE", nil)]]; + _verificationStepView.accessibilityIdentifier = ORKVerificationStepViewAccessibilityIdentifier; _iPadContentView = [self viewForiPadLayoutConstraints]; if (_iPadContentView) { @@ -71,6 +75,7 @@ - (void)stepDidChange { [_verificationStepView.resendEmailButton addTarget:self action:@selector(resendEmailButtonHandler:) forControlEvents:UIControlEventTouchUpInside]; + _verificationStepView.resendEmailButton.accessibilityIdentifier = ORKVerificationStepViewResendEmailButtonAccessibilityIdentifier; } } diff --git a/ResearchKitUI/PrivacyInfo.xcprivacy b/ResearchKitUI/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..42deda33af --- /dev/null +++ b/ResearchKitUI/PrivacyInfo.xcprivacy @@ -0,0 +1,63 @@ + + + + + NSPrivacyAccessedAPITypes + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypePhotosorVideos + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeSensitiveInfo + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeHealth + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypePreciseLocation + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + + diff --git a/ResearchKitUI/ResearchKitUI.h b/ResearchKitUI/ResearchKitUI.h index b37546101c..4c1733f277 100644 --- a/ResearchKitUI/ResearchKitUI.h +++ b/ResearchKitUI/ResearchKitUI.h @@ -44,7 +44,6 @@ #import #import #import -#import #import #import #import @@ -96,6 +95,7 @@ #import #import #import +#import #import #import #import diff --git a/ResearchKitUI/ResearchKitUI.modulemap b/ResearchKitUI/ResearchKitUI.modulemap index f463c5f550..ac669dcd68 100644 --- a/ResearchKitUI/ResearchKitUI.modulemap +++ b/ResearchKitUI/ResearchKitUI.modulemap @@ -5,10 +5,3 @@ framework module ResearchKitUI { export * module * { export * } } - -framework module ResearchKitUI_Private { - umbrella header "ResearchKitUI_Private.h" - - export * - module * { export * } -} diff --git a/ResearchKitUI/ResearchKitUI_Private.modulemap b/ResearchKitUI/ResearchKitUI_Private.modulemap new file mode 100644 index 0000000000..b490d6475b --- /dev/null +++ b/ResearchKitUI/ResearchKitUI_Private.modulemap @@ -0,0 +1,36 @@ +/* + Copyright (c) 2024, 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. + */ + +framework module ResearchKitUI_Private { + umbrella header "ResearchKitUI_Private.h" + + export * + module * { export * } +} diff --git a/samples/ORKCatalog/ORKCatalog.xcodeproj/project.pbxproj b/samples/ORKCatalog/ORKCatalog.xcodeproj/project.pbxproj index 140751df60..9fe0c6553c 100644 --- a/samples/ORKCatalog/ORKCatalog.xcodeproj/project.pbxproj +++ b/samples/ORKCatalog/ORKCatalog.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ 3E39BA001ABF683F00C2ABE5 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3E39B9FF1ABF683F00C2ABE5 /* Images.xcassets */; }; 3ED967B81AC13D37007E2D83 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3ED967BA1AC13D37007E2D83 /* Localizable.strings */; }; 51AF19862B59F3A900D3B399 /* ORKKeychainWrapperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 51AF19852B59F3A900D3B399 /* ORKKeychainWrapperTests.m */; }; + 51C173282BA4B4E1006604FB /* sphere_model.usdz in Resources */ = {isa = PBXBuildFile; fileRef = 51C173272BA4B4E1006604FB /* sphere_model.usdz */; }; 51F210EF2B4634FC0072B536 /* TaskListRowSteps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F210EE2B4634FC0072B536 /* TaskListRowSteps.swift */; }; 51F210FE2B49D04F0072B536 /* TaskListRowConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F210FD2B49D04F0072B536 /* TaskListRowConstants.swift */; }; 863CCD821ACF545E009FD3B4 /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 863CCD811ACF545E009FD3B4 /* HealthKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; @@ -121,6 +122,7 @@ 5116D0BF2677FB780010FAB1 /* ResearchKit-Shared.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "ResearchKit-Shared.xcconfig"; sourceTree = ""; }; 51AF19772B59F1E400D3B399 /* ORKCatalogTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ORKCatalogTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 51AF19852B59F3A900D3B399 /* ORKKeychainWrapperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKKeychainWrapperTests.m; sourceTree = ""; }; + 51C173272BA4B4E1006604FB /* sphere_model.usdz */ = {isa = PBXFileReference; lastKnownFileType = file.usdz; path = sphere_model.usdz; sourceTree = ""; }; 51F210EE2B4634FC0072B536 /* TaskListRowSteps.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskListRowSteps.swift; sourceTree = ""; }; 51F210FD2B49D04F0072B536 /* TaskListRowConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskListRowConstants.swift; sourceTree = ""; }; 863CCD811ACF545E009FD3B4 /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; }; @@ -309,6 +311,7 @@ BC74787A1B990EED0072BFE8 /* Resources */ = { isa = PBXGroup; children = ( + 51C173272BA4B4E1006604FB /* sphere_model.usdz */, BAAC3FD520C4EF1C0065B9E1 /* ResearchKit.pdf */, 3E39B9FF1ABF683F00C2ABE5 /* Images.xcassets */, 3E39B9FC1ABF683700C2ABE5 /* LaunchScreen.xib */, @@ -483,6 +486,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 51C173282BA4B4E1006604FB /* sphere_model.usdz in Resources */, 3E39BA001ABF683F00C2ABE5 /* Images.xcassets in Resources */, 3E39B9FB1ABF682D00C2ABE5 /* Main.storyboard in Resources */, BAAC3FD620C4EF1C0065B9E1 /* ResearchKit.pdf in Resources */, diff --git a/samples/ORKCatalog/ORKCatalog/Resources/sphere_model.usdz b/samples/ORKCatalog/ORKCatalog/Resources/sphere_model.usdz new file mode 100644 index 0000000000..7c8e4db04d Binary files /dev/null and b/samples/ORKCatalog/ORKCatalog/Resources/sphere_model.usdz differ diff --git a/samples/ORKCatalog/ORKCatalog/Results/ResultTableViewProviders.swift b/samples/ORKCatalog/ORKCatalog/Results/ResultTableViewProviders.swift index c9b8cbb96f..3263ce15e3 100644 --- a/samples/ORKCatalog/ORKCatalog/Results/ResultTableViewProviders.swift +++ b/samples/ORKCatalog/ORKCatalog/Results/ResultTableViewProviders.swift @@ -164,6 +164,7 @@ func resultTableViewProviderForResult(_ result: ORKResult?, delegate: ResultProv */ case is ORKCollectionResult where !(result is ORKTaskResult): providerType = CollectionResultTableViewProvider.self + case is ORKVideoInstructionStepResult: providerType = VideoInstructionStepResultTableViewProvider.self @@ -180,7 +181,6 @@ func resultTableViewProviderForResult(_ result: ORKResult?, delegate: ResultProv case is ORKSignatureResult: providerType = SignatureResultTableViewProvider.self - default: fatalError("No ResultTableViewProvider defined for \(type(of: result)).") } diff --git a/samples/ORKCatalog/ORKCatalog/TaskListRowConstants.swift b/samples/ORKCatalog/ORKCatalog/TaskListRowConstants.swift index 78771ccb5c..4fa9c2ddbe 100644 --- a/samples/ORKCatalog/ORKCatalog/TaskListRowConstants.swift +++ b/samples/ORKCatalog/ORKCatalog/TaskListRowConstants.swift @@ -287,6 +287,9 @@ enum Identifier { case webViewTask case webViewStep + // 3DModelStep tasks + case usdzModelStep + case usdzModelTask } diff --git a/samples/ORKCatalog/ORKCatalog/TaskListRowSteps.swift b/samples/ORKCatalog/ORKCatalog/TaskListRowSteps.swift index e3622b02a9..a587fbf84e 100644 --- a/samples/ORKCatalog/ORKCatalog/TaskListRowSteps.swift +++ b/samples/ORKCatalog/ORKCatalog/TaskListRowSteps.swift @@ -28,7 +28,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import ResearchKit +import ResearchKitActiveTask enum TaskListRowSteps { @@ -197,6 +197,54 @@ enum TaskListRowSteps { return emailFormStep } + static var groupFormExample: ORKFormStep { + let step = ORKFormStep(identifier: String(describing: Identifier.groupedFormStep), + title: NSLocalizedString("Form Step", comment: ""), + text: TaskListRowStrings.exampleDetailText) + + //Start of first section + let learnMoreInstructionStep01 = ORKLearnMoreInstructionStep(identifier: "LearnMoreInstructionStep01") + learnMoreInstructionStep01.title = NSLocalizedString("Learn more title", comment: "") + learnMoreInstructionStep01.text = NSLocalizedString("Learn more text", comment: "") + let learnMoreItem01 = ORKLearnMoreItem(text: nil, learnMoreInstructionStep: learnMoreInstructionStep01) + let section01 = ORKFormItem(sectionTitle: NSLocalizedString("Section title", comment: ""), detailText: NSLocalizedString("Section detail text", comment: ""), learnMoreItem: learnMoreItem01, showsProgress: true) + + // A first field, for entering an integer. + let formItem01Text = NSLocalizedString("Field01", comment: "") + let formItem01 = ORKFormItem(identifier: String(describing: Identifier.formItem01), text: formItem01Text, answerFormat: ORKAnswerFormat.integerAnswerFormat(withUnit: nil)) + formItem01.placeholder = NSLocalizedString("Your placeholder here", comment: "") + + // A second field, for entering a time interval. + let formItem02Text = NSLocalizedString("Field02", comment: "") + let formItem02 = ORKFormItem(identifier: String(describing: Identifier.formItem02), text: formItem02Text, answerFormat: ORKTimeIntervalAnswerFormat()) + formItem02.placeholder = NSLocalizedString("Your placeholder here", comment: "") + + let textOnlySection = ORKFormItem(sectionTitle: NSLocalizedString("Text Only Section", comment: ""), detailText: NSLocalizedString("Text section text", comment: ""), learnMoreItem: learnMoreItem01, showsProgress: true) + let textOnlyFormItemA = ORKFormItem(identifier: "text-section-text-item-a", text: "Text Field A", answerFormat: ORKTextAnswerFormat()) + let textOnlyFormItemB = ORKFormItem(identifier: "text-section-text-item-b", text: "Text Field B", answerFormat: ORKTimeIntervalAnswerFormat()) + + let sesAnswerFormat = ORKSESAnswerFormat(topRungText: "Best Off", bottomRungText: "Worst Off") + let sesFormItem = ORKFormItem(identifier: "sesIdentifier", text: "Select where you are on the socioeconomic ladder.", answerFormat: sesAnswerFormat) + + //Start of section for scale question + let formItem03Text = TaskListRowStrings.exampleQuestionText + let scaleAnswerFormat = ORKContinuousScaleAnswerFormat(maximumValue: 10, minimumValue: 0, defaultValue: 0.0, maximumFractionDigits: 1) + let formItem03 = ORKFormItem(identifier: String(describing: Identifier.formItem03), text: formItem03Text, detailText: nil, learnMoreItem: nil, showsProgress: true, answerFormat: scaleAnswerFormat, tagText: nil, optional: true) + + step.formItems = [ + section01, + formItem01, + formItem02, + textOnlySection, + textOnlyFormItemA, + textOnlyFormItemB, + formItem03, + sesFormItem + ] + + return step + } + static var heartRateExample: ORKFormStep { let heartRateType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate)! let heartRateAnswerFormat = ORKHealthKitQuantityTypeAnswerFormat(quantityType: heartRateType, @@ -612,25 +660,33 @@ enum TaskListRowSteps { detailText: nil, image: UIImage(systemName: "heart.fill"), learnMoreItem: nil, - bodyItemStyle: .image) + bodyItemStyle: .image, + useCardStyle: false, + alignImageToTop: true) let completingTasksBodyItem = ORKBodyItem(text: "You will be asked to complete various tasks over the duration of the study.", detailText: nil, image: UIImage(systemName: "checkmark.circle.fill"), learnMoreItem: nil, - bodyItemStyle: .image) + bodyItemStyle: .image, + useCardStyle: false, + alignImageToTop: true) let signatureBodyItem = ORKBodyItem(text: "Before joining, we will ask you to sign an informed consent document.", detailText: nil, image: UIImage(systemName: "signature"), learnMoreItem: nil, - bodyItemStyle: .image) + bodyItemStyle: .image, + useCardStyle: false, + alignImageToTop: true) let secureDataBodyItem = ORKBodyItem(text: "Your data is kept private and secure.", detailText: nil, image: UIImage(systemName: "lock.fill"), learnMoreItem: nil, - bodyItemStyle: .image) + bodyItemStyle: .image, + useCardStyle: false, + alignImageToTop: true) instructionStep.bodyItems = [ sharingHealthDataBodyItem, @@ -713,6 +769,21 @@ enum TaskListRowSteps { return embeddedReviewStep } + // MARK: - ORK3DModelStep + + static var usdzModelExample: ORK3DModelStep { + let modelManager = ORKUSDZModelManager(usdzFileName: "sphere_model") + modelManager.allowsSelection = true + modelManager.enableContinueAfterSelection = true + modelManager.highlightColor = .systemBlue + + let usdzModelStep = ORK3DModelStep(identifier: String(describing: Identifier.usdzModelStep), modelManager: modelManager) + usdzModelStep.title = "Example USDZ Model" + usdzModelStep.text = "Tap the model to continue" + + return usdzModelStep + } + // MARK: - Helpers private static var formItemSectionHeaderExample: ORKFormItem { diff --git a/samples/ORKCatalog/ORKCatalog/Tasks/TaskListRow.swift b/samples/ORKCatalog/ORKCatalog/Tasks/TaskListRow.swift index 26a4c6192c..a4817ce05d 100644 --- a/samples/ORKCatalog/ORKCatalog/Tasks/TaskListRow.swift +++ b/samples/ORKCatalog/ORKCatalog/Tasks/TaskListRow.swift @@ -66,6 +66,7 @@ class SystemSound { enum TaskListRow: Int, CustomStringConvertible { case form = 0 case groupedForm + case groupedFormNoScroll case survey case dontknowSurvey case surveyWithMultipleOptions @@ -129,6 +130,7 @@ enum TaskListRow: Int, CustomStringConvertible { case webView case consentTask case consentDoc + case usdzModel class TaskListRowSection { @@ -144,11 +146,12 @@ enum TaskListRow: Int, CustomStringConvertible { /// Returns an array of all the task list row enum cases. static var sections: [ TaskListRowSection ] { - var defaultSections = [ + let defaultSections = [ TaskListRowSection(title: "Surveys", rows: [ .dontknowSurvey, .groupedForm, + .groupedFormNoScroll, .form, .survey, .surveyWithMultipleOptions @@ -192,6 +195,7 @@ enum TaskListRow: Int, CustomStringConvertible { .imageCapture, .PDFViewer, .requestPermissions, + .usdzModel, .videoCapture, .videoInstruction, .wait, @@ -234,13 +238,16 @@ enum TaskListRow: Int, CustomStringConvertible { var description: String { switch self { case .form: - return NSLocalizedString("Form Survey Example", comment: "") + return NSLocalizedString("Form Survey", comment: "") case .groupedForm: - return NSLocalizedString("Grouped Form Survey Example", comment: "") + return NSLocalizedString("Grouped Form Survey", comment: "") + + case .groupedFormNoScroll: + return NSLocalizedString("Grouped Form Survey No AutoScroll", comment: "") case .survey: - return NSLocalizedString("Simple Survey Example", comment: "") + return NSLocalizedString("Simple Survey", comment: "") case .dontknowSurvey: return NSLocalizedString("Don't Know Survey", comment: "") @@ -425,6 +432,9 @@ enum TaskListRow: Int, CustomStringConvertible { case .consentDoc: return NSLocalizedString("Consent Document Review", comment: "") + case .usdzModel: + return NSLocalizedString("USDZ Model", comment: "") + case .surveyWithMultipleOptions: return NSLocalizedString("Survey With Multiple Options", comment: "") } @@ -440,6 +450,9 @@ enum TaskListRow: Int, CustomStringConvertible { case .groupedForm: return groupedFormTask + + case .groupedFormNoScroll: + return groupedFormTaskNoScroll case .surveyWithMultipleOptions: return formTaskWithMultipleOptions @@ -627,6 +640,9 @@ enum TaskListRow: Int, CustomStringConvertible { case .consentDoc: return consentDoc + case .usdzModel: + return usdzModel + case .textChoiceQuestionWithImageTask: return textChoiceQuestionWithImageTask @@ -865,47 +881,7 @@ enum TaskListRow: Int, CustomStringConvertible { } private var groupedFormTask: ORKTask { - let step = ORKFormStep(identifier: String(describing: Identifier.groupedFormStep), title: NSLocalizedString("Form Step", comment: ""), text: TaskListRowStrings.exampleDetailText) - - //Start of first section - let learnMoreInstructionStep01 = ORKLearnMoreInstructionStep(identifier: "LearnMoreInstructionStep01") - learnMoreInstructionStep01.title = NSLocalizedString("Learn more title", comment: "") - learnMoreInstructionStep01.text = NSLocalizedString("Learn more text", comment: "") - let learnMoreItem01 = ORKLearnMoreItem(text: nil, learnMoreInstructionStep: learnMoreInstructionStep01) - let section01 = ORKFormItem(sectionTitle: NSLocalizedString("Section title", comment: ""), detailText: NSLocalizedString("Section detail text", comment: ""), learnMoreItem: learnMoreItem01, showsProgress: true) - - // A first field, for entering an integer. - let formItem01Text = NSLocalizedString("Field01", comment: "") - let formItem01 = ORKFormItem(identifier: String(describing: Identifier.formItem01), text: formItem01Text, answerFormat: ORKAnswerFormat.integerAnswerFormat(withUnit: nil)) - formItem01.placeholder = NSLocalizedString("Your placeholder here", comment: "") - - // A second field, for entering a time interval. - let formItem02Text = NSLocalizedString("Field02", comment: "") - let formItem02 = ORKFormItem(identifier: String(describing: Identifier.formItem02), text: formItem02Text, answerFormat: ORKTimeIntervalAnswerFormat()) - formItem02.placeholder = NSLocalizedString("Your placeholder here", comment: "") - - let textOnlySection = ORKFormItem(sectionTitle: NSLocalizedString("Text Only Section", comment: ""), detailText: NSLocalizedString("Text section text", comment: ""), learnMoreItem: learnMoreItem01, showsProgress: true) - let textOnlyFormItemA = ORKFormItem(identifier: "text-section-text-item-a", text: "Text Field A", answerFormat: ORKTextAnswerFormat()) - let textOnlyFormItemB = ORKFormItem(identifier: "text-section-text-item-b", text: "Text Field B", answerFormat: ORKTimeIntervalAnswerFormat()) - - let sesAnswerFormat = ORKSESAnswerFormat(topRungText: "Best Off", bottomRungText: "Worst Off") - let sesFormItem = ORKFormItem(identifier: "sesIdentifier", text: "Select where you are on the socioeconomic ladder.", answerFormat: sesAnswerFormat) - - //Start of section for scale question - let formItem03Text = TaskListRowStrings.exampleQuestionText - let scaleAnswerFormat = ORKContinuousScaleAnswerFormat(maximumValue: 10, minimumValue: 0, defaultValue: 0.0, maximumFractionDigits: 1)//ORKScaleAnswerFormat(maximumValue: 10, minimumValue: 0, defaultValue: 0, step: 1) - let formItem03 = ORKFormItem(identifier: String(describing: Identifier.formItem03), text: formItem03Text, detailText: nil, learnMoreItem: nil, showsProgress: true, answerFormat: scaleAnswerFormat, tagText: nil, optional: true) - - step.formItems = [ - section01, - formItem01, - formItem02, - textOnlySection, - textOnlyFormItemA, - textOnlyFormItemB, - formItem03, - sesFormItem - ] + let step = TaskListRowSteps.groupFormExample let booleanQuestionFormStep = TaskListRowSteps.booleanExample @@ -934,6 +910,13 @@ enum TaskListRow: Int, CustomStringConvertible { return ORKOrderedTask(identifier: String(describing: Identifier.groupedFormTask), steps: [step, booleanQuestionFormStep, birthdayQuestionFormStep, appleFormStep]) } + + private var groupedFormTaskNoScroll: ORKTask { + let groupedFormStep = TaskListRowSteps.groupFormExample + groupedFormStep.autoScrollEnabled = false + + return ORKOrderedTask(identifier: String(describing: Identifier.groupedFormTask), steps: [groupedFormStep]) + } /** A task demonstrating how the ResearchKit framework can be used to present a simple @@ -1775,5 +1758,10 @@ enum TaskListRow: Int, CustomStringConvertible { let webViewStep = TaskListRowSteps.webViewStepExample return ORKOrderedTask(identifier: String(describing: Identifier.webViewTask), steps: [webViewStep]) } + + private var usdzModel: ORKTask { + let usdzModelStep = TaskListRowSteps.usdzModelExample + return ORKOrderedTask(identifier: String(describing: Identifier.usdzModelTask), steps: [usdzModelStep]) + } }