Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7a8990260c | |||
| 9b1153da04 | |||
| 38d161f1bf |
@@ -1,3 +1,6 @@
|
||||
|
||||

|
||||
|
||||
ResearchKit Framework
|
||||
===========
|
||||
|
||||
|
||||
@@ -1,5 +1,50 @@
|
||||
# ResearchKit Release Notes
|
||||
|
||||
## ResearchKit 3.1.1 Release Notes
|
||||
General bug fixes for the following:
|
||||
|
||||
- **ORKMotionActivityPermissionType**
|
||||
Fixed issue that caused the next button to remain disabled after gaining permission from user.
|
||||
|
||||
- **ORKRegistrationStep**
|
||||
Removed yellow overlay that prevented password entry.
|
||||
|
||||
- **ORKdBHLToneAudiometryStep**
|
||||
Fixed issue that caused the tap button to appear twice.
|
||||
|
||||
|
||||
## ResearchKit 3.1 Release Notes
|
||||
In addition to general stability and performance improvements, ResearchKit 3.1 includes the following updates:
|
||||
|
||||
- **ORKFamilyHistoryStep**
|
||||
The `ORKFamilyHistoryStep` can be configured to present a Family Health History survey.
|
||||
|
||||
- **ORKColorChoiceAnswerFormat**
|
||||
The `ORKColorChoiceAnswerFormat` presents the user with a list of color choices.
|
||||
|
||||
- **ORKAgeAnswerFormat**
|
||||
The `ORKAgeAnswerFormat` presents a age picker that presents birth year or current age options depending on how you configure it.
|
||||
|
||||
- **CLLocation Flag**
|
||||
A compiler flag that prevents your app from being flagged during app store submission if your app doesn't require location services.
|
||||
|
||||
- **HealthKit Flag**
|
||||
A compiler flag that prevents your app from being flagged during app store submission if your app doesn't use HealthKit.
|
||||
|
||||
|
||||
## 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
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'ResearchKit'
|
||||
s.version = '3.0.1'
|
||||
s.summary = 'ResearchKit is an open source software framework that makes it easy to create apps for medical research or for other research projects.'
|
||||
s.homepage = 'https://www.github.com/ResearchKit/ResearchKit'
|
||||
s.documentation_url = 'http://researchkit.github.io/docs/'
|
||||
s.license = { :type => 'BSD', :file => 'LICENSE' }
|
||||
s.author = { 'researchkit.org' => 'http://researchkit.org' }
|
||||
s.source = { :git => 'https://github.com/ResearchKit/ResearchKit.git', :tag => s.version.to_s }
|
||||
|
||||
s.default_subspec = "ResearchKitAllTargets"
|
||||
|
||||
s.subspec 'ResearchKitCore' do |ss|
|
||||
ss.vendored_frameworks = 'xcframework/ResearchKit.xcframework'
|
||||
end
|
||||
|
||||
s.subspec 'ResearchKitUI' do |ss|
|
||||
ss.vendored_frameworks = 'xcframework/ResearchKitUI.xcframework'
|
||||
ss.dependency 'ResearchKit/ResearchKitCore'
|
||||
end
|
||||
|
||||
s.subspec 'ResearchKitActiveTask' do |ss|
|
||||
ss.vendored_frameworks = 'xcframework/ResearchKitActiveTask.xcframework'
|
||||
ss.dependency 'ResearchKit/ResearchKitUI'
|
||||
ss.dependency 'ResearchKit/ResearchKitCore'
|
||||
end
|
||||
|
||||
s.subspec 'ResearchKitAllTargets' do |ss|
|
||||
ss.dependency 'ResearchKit/ResearchKitCore'
|
||||
ss.dependency 'ResearchKit/ResearchKitUI'
|
||||
ss.dependency 'ResearchKit/ResearchKitActiveTask'
|
||||
end
|
||||
end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B183A4731A8535D100C76870"
|
||||
BuildableName = ".framework"
|
||||
BuildableName = "ResearchKit.framework"
|
||||
BlueprintName = "ResearchKit"
|
||||
ReferencedContainer = "container:ResearchKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
@@ -51,7 +51,7 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B183A4731A8535D100C76870"
|
||||
BuildableName = ".framework"
|
||||
BuildableName = "ResearchKit.framework"
|
||||
BlueprintName = "ResearchKit"
|
||||
ReferencedContainer = "container:ResearchKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
@@ -67,7 +67,7 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B183A4731A8535D100C76870"
|
||||
BuildableName = ".framework"
|
||||
BuildableName = "ResearchKit.framework"
|
||||
BlueprintName = "ResearchKit"
|
||||
ReferencedContainer = "container:ResearchKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1530"
|
||||
version = "1.7">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES"
|
||||
buildArchitectures = "Automatic">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "CAD08966289DD747007B2A98"
|
||||
BuildableName = "ResearchKitActiveTask.framework"
|
||||
BlueprintName = "ResearchKitActiveTask"
|
||||
ReferencedContainer = "container:ResearchKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
shouldAutocreateTestPlan = "YES">
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "CAD08966289DD747007B2A98"
|
||||
BuildableName = "ResearchKitActiveTask.framework"
|
||||
BlueprintName = "ResearchKitActiveTask"
|
||||
ReferencedContainer = "container:ResearchKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
<InstallAction
|
||||
buildConfiguration = "Release">
|
||||
</InstallAction>
|
||||
</Scheme>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1530"
|
||||
version = "1.7">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES"
|
||||
buildArchitectures = "Automatic">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "0BC672D82BD9C52D005798AC"
|
||||
BuildableName = "ResearchKitAllTargets"
|
||||
BlueprintName = "ResearchKitAllTargets"
|
||||
ReferencedContainer = "container:ResearchKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
shouldAutocreateTestPlan = "YES">
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "0BC672D82BD9C52D005798AC"
|
||||
BuildableName = "ResearchKitAllTargets"
|
||||
BlueprintName = "ResearchKitAllTargets"
|
||||
ReferencedContainer = "container:ResearchKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
<InstallAction
|
||||
buildConfiguration = "Release">
|
||||
</InstallAction>
|
||||
</Scheme>
|
||||
@@ -33,7 +33,7 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B183A4731A8535D100C76870"
|
||||
BuildableName = ".framework"
|
||||
BuildableName = "ResearchKit.framework"
|
||||
BlueprintName = "ResearchKit"
|
||||
ReferencedContainer = "container:ResearchKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "CA1C7A40288B0C68004DAB3A"
|
||||
BuildableName = "ResearchKitUI.framework"
|
||||
BlueprintName = "ResearchKitUI (iOS)"
|
||||
BlueprintName = "ResearchKitUI"
|
||||
ReferencedContainer = "container:ResearchKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
@@ -52,7 +52,7 @@
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "CA1C7A40288B0C68004DAB3A"
|
||||
BuildableName = "ResearchKitUI.framework"
|
||||
BlueprintName = "ResearchKitUI (iOS)"
|
||||
BlueprintName = "ResearchKitUI"
|
||||
ReferencedContainer = "container:ResearchKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
@@ -28,6 +28,7 @@
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
#import <CoreLocation/CLLocationManager.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@@ -52,3 +53,4 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
#endif
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
#import "CLLocationManager+ResearchKit.h"
|
||||
|
||||
#import "ORKDefines.h"
|
||||
@@ -35,37 +36,22 @@
|
||||
@implementation CLLocationManager (ResearchKit)
|
||||
|
||||
- (BOOL)ork_requestWhenInUseAuthorization {
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
[self requestWhenInUseAuthorization];
|
||||
return YES;
|
||||
#else
|
||||
return NO;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (BOOL)ork_requestAlwaysAuthorization {
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
[self requestAlwaysAuthorization];
|
||||
return YES;
|
||||
#else
|
||||
return NO;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)ork_startUpdatingLocation {
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
[self startUpdatingLocation];
|
||||
#else
|
||||
// noop
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)ork_stopUpdatingLocation {
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
[self stopUpdatingLocation];
|
||||
#else
|
||||
// noop
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
*/
|
||||
|
||||
|
||||
@import CoreMotion;
|
||||
#import <CoreMotion/CoreMotion.h>
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
+4
-1
@@ -29,7 +29,8 @@
|
||||
*/
|
||||
|
||||
|
||||
@import HealthKit;
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
#import <HealthKit/HealthKit.h>
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@@ -60,3 +61,5 @@ typedef NS_OPTIONS(NSInteger, ORKSampleJSONOptions) {
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif
|
||||
+2
-1
@@ -45,7 +45,7 @@ static NSString *const HKUnitKey = @"unit";
|
||||
static NSString *const HKCorrelatedObjectsKey = @"objects";
|
||||
// static NSString *const HKSourceIdentifierKey = @"sourceBundleIdentifier";
|
||||
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
@implementation HKSample (ORKJSONDictionary)
|
||||
|
||||
- (NSMutableDictionary *)ork_JSONMutableDictionaryWithOptions:(ORKSampleJSONOptions)options unit:(HKUnit *)unit {
|
||||
@@ -167,3 +167,4 @@ static NSString *const HKCorrelatedObjectsKey = @"objects";
|
||||
}
|
||||
|
||||
@end
|
||||
#endif // ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
@@ -30,7 +30,6 @@
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <HealthKit/HealthKit.h>
|
||||
#import <ResearchKit/ORKStep.h>
|
||||
|
||||
|
||||
|
||||
@@ -164,6 +164,7 @@
|
||||
(self.shouldUseNextAsSkipButton == castObject.shouldUseNextAsSkipButton));
|
||||
}
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
- (NSSet<HKObjectType *> *)requestedHealthKitTypesForReading {
|
||||
NSMutableSet<HKObjectType *> *set = [NSMutableSet set];
|
||||
for (ORKRecorderConfiguration *config in self.recorderConfigurations) {
|
||||
@@ -174,6 +175,7 @@
|
||||
}
|
||||
return set;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (ORKPermissionMask)requestedPermissions {
|
||||
ORKPermissionMask mask = [super requestedPermissions];
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class ORKBooleanAnswerFormat;
|
||||
@class ORKColorChoiceAnswerFormat;
|
||||
@class ORKColorChoice;
|
||||
@class ORKTextChoiceAnswerFormat;
|
||||
@class ORKTextChoice;
|
||||
|
||||
@@ -123,6 +125,8 @@ ORK_CLASS_AVAILABLE
|
||||
+ (ORKTextChoiceAnswerFormat *)choiceAnswerFormatWithStyle:(ORKChoiceAnswerStyle)style
|
||||
textChoices:(NSArray<ORKTextChoice *> *)textChoices;
|
||||
|
||||
+ (ORKColorChoiceAnswerFormat *)choiceAnswerFormatWithStyle:(ORKChoiceAnswerStyle)style
|
||||
colorChoices:(NSArray<ORKColorChoice *> *)colorChoices;
|
||||
|
||||
/// @name Validation
|
||||
|
||||
@@ -189,9 +193,29 @@ ORK_CLASS_AVAILABLE
|
||||
*/
|
||||
@property (copy, readonly) NSArray<ORKTextChoice *> *textChoices;
|
||||
|
||||
/**
|
||||
Returns YES if the answer is no longer valid, specifically used in the ORKFormStep Restoration
|
||||
*/
|
||||
- (BOOL)isAnswerInvalid:(id)answer;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKColorChoiceAnswerFormat : ORKAnswerFormat
|
||||
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initWithStyle:(ORKChoiceAnswerStyle)style
|
||||
colorChoices:(NSArray<ORKColorChoice *> *)colorChoices NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@property (readonly) ORKChoiceAnswerStyle style;
|
||||
|
||||
@property (copy, readonly) NSArray<ORKColorChoice *> *colorChoices;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/**
|
||||
The `ORKBooleanAnswerFormat` class behaves the same as the `ORKTextChoiceAnswerFormat` class,
|
||||
@@ -386,6 +410,34 @@ ORK_CLASS_AVAILABLE
|
||||
@end
|
||||
|
||||
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKColorChoice: NSObject <NSSecureCoding, NSCopying, NSObject>
|
||||
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initWithColor:(nullable UIColor *)color
|
||||
text:(nullable NSString *)text
|
||||
detailText:(nullable NSString *)detailText
|
||||
value:(NSObject<NSCopying, NSSecureCoding> *)value;
|
||||
|
||||
- (instancetype)initWithColor:(nullable UIColor *)color
|
||||
text:(nullable NSString *)text
|
||||
detailText:(nullable NSString *)detailText
|
||||
value:(NSObject<NSCopying, NSSecureCoding> *)value
|
||||
exclusive:(BOOL)exclusive;
|
||||
|
||||
@property (nonatomic, copy, readonly, nullable) UIColor *color;
|
||||
|
||||
@property (nonatomic, copy, readonly, nullable) NSString *text;
|
||||
|
||||
@property (nonatomic, copy, readonly, nullable) NSString *detailText;
|
||||
|
||||
@property (nonatomic, copy, readonly) NSObject<NSCopying, NSSecureCoding> *value;
|
||||
|
||||
@property (readonly) BOOL exclusive;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - iOS
|
||||
@@ -480,8 +532,9 @@ ORK_CLASS_AVAILABLE
|
||||
minimumValue:(double)minimumValue
|
||||
maximumValue:(double)maximumValue
|
||||
defaultValue:(double)defaultValue;
|
||||
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
+ (ORKLocationAnswerFormat *)locationAnswerFormat;
|
||||
#endif
|
||||
|
||||
+ (ORKSESAnswerFormat *)socioEconomicAnswerFormatWithTopRungText:(NSString *)topRungText bottomRungText:(NSString *)bottomRungText;
|
||||
|
||||
@@ -2026,6 +2079,134 @@ ORK_CLASS_AVAILABLE
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
The `ORKAgeAnswerFormat` class represents the answer format for questions that require users
|
||||
to enter a weight.
|
||||
|
||||
A weight answer format produces an `ORKNumericQuestionResult` object. The result is always reported
|
||||
in the metric system using the `kg` unit.
|
||||
*/
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKAgeAnswerFormat : ORKAnswerFormat
|
||||
|
||||
/**
|
||||
Returns an initialized weight answer format using the measurement system specified in the current
|
||||
locale.
|
||||
|
||||
@return An initialized weight answer format.
|
||||
*/
|
||||
- (instancetype)init;
|
||||
|
||||
- (instancetype)initWithMinimumAge:(NSInteger)minimumAge
|
||||
maximumAge:(NSInteger)maximumAge;
|
||||
|
||||
- (instancetype)initWithMinimumAge:(NSInteger)minimumAge
|
||||
maximumAge:(NSInteger)maximumAge
|
||||
minimumAgeCustomText:(nullable NSString *)minimumAgeCustomText
|
||||
maximumAgeCustomText:(nullable NSString *)maximumAgeCustomText
|
||||
showYear:(BOOL)showYear
|
||||
useYearForResult:(BOOL)useYearForResult
|
||||
defaultValue:(NSInteger)defaultValue;
|
||||
|
||||
- (instancetype)initWithMinimumAge:(NSInteger)minimumAge
|
||||
maximumAge:(NSInteger)maximumAge
|
||||
minimumAgeCustomText:(nullable NSString *)minimumAgeCustomText
|
||||
maximumAgeCustomText:(nullable NSString *)maximumAgeCustomText
|
||||
showYear:(BOOL)showYear
|
||||
useYearForResult:(BOOL)useYearForResult
|
||||
treatMinAgeAsRange:(BOOL)treatMinAgeAsRange
|
||||
treatMaxAgeAsRange:(BOOL)treatMaxAgeAsRange
|
||||
defaultValue:(NSInteger)defaultValue;
|
||||
|
||||
+ (int)minimumAgeSentinelValue;
|
||||
+ (int)maximumAgeSentinelValue;
|
||||
|
||||
/**
|
||||
Minimum age value presented in the picker
|
||||
|
||||
By default, the value of this property is 0.
|
||||
*/
|
||||
@property (readonly) NSInteger minimumAge;
|
||||
|
||||
|
||||
/**
|
||||
Maximum age value presented in the picker.
|
||||
|
||||
By default, the value of this property is 125.
|
||||
*/
|
||||
@property (readonly) NSInteger maximumAge;
|
||||
|
||||
|
||||
/**
|
||||
Custom text that will replace the minimumAge value.
|
||||
|
||||
By default, the value of this property is nil.
|
||||
*/
|
||||
|
||||
@property (readonly, nullable) NSString *minimumAgeCustomText;
|
||||
|
||||
/**
|
||||
Custom text that will replace the maximumAge value.
|
||||
|
||||
By default, the value of this property is nil.
|
||||
*/
|
||||
|
||||
@property (readonly, nullable) NSString *maximumAgeCustomText;
|
||||
|
||||
|
||||
/**
|
||||
Boolean that determines if the year should be shown alongside the age value.
|
||||
|
||||
By default, the value of this property is nil.
|
||||
*/
|
||||
|
||||
@property (readonly) BOOL showYear;
|
||||
|
||||
/**
|
||||
The year at which the picker will base all of its ages from.
|
||||
|
||||
By default, the value of this property will be the current year.
|
||||
*/
|
||||
|
||||
@property (nonatomic) NSInteger relativeYear;
|
||||
|
||||
|
||||
/**
|
||||
Boolean that determines if the year for the selected age should be used in the result.
|
||||
|
||||
By default, the value of this property is NO.
|
||||
*/
|
||||
|
||||
@property (readonly) BOOL useYearForResult;
|
||||
|
||||
/**
|
||||
Boolean that determines if the minimumAge property should be treated as range.
|
||||
|
||||
-1 will be returned if minimumAge is selected
|
||||
|
||||
By default, the value of this property is NO.
|
||||
*/
|
||||
|
||||
@property (readonly) BOOL treatMinAgeAsRange;
|
||||
|
||||
/**
|
||||
Boolean that determines if the maximumAge property should be treated as range.
|
||||
|
||||
-2 will be returned if maximumAge is selected
|
||||
|
||||
By default, the value of this property is NO.
|
||||
*/
|
||||
|
||||
@property (readonly) BOOL treatMaxAgeAsRange;
|
||||
|
||||
/**
|
||||
The default value for the picker.
|
||||
*/
|
||||
|
||||
@property (readonly) NSInteger defaultValue;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/**
|
||||
The `ORKLocationAnswerFormat` class represents the answer format for questions that collect a location response
|
||||
@@ -2033,6 +2214,7 @@ ORK_CLASS_AVAILABLE
|
||||
|
||||
An `ORKLocationAnswerFormat` object produces an `ORKLocationQuestionResult` object.
|
||||
*/
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKLocationAnswerFormat : ORKAnswerFormat
|
||||
|
||||
@@ -2051,6 +2233,7 @@ ORK_CLASS_AVAILABLE
|
||||
@property (copy, nullable) NSString *placeholder;
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
||||
/**
|
||||
Socio-Economic Ladder Answer Format.
|
||||
|
||||
@@ -44,8 +44,10 @@
|
||||
#import "ResearchKit/ResearchKit-Swift.h"
|
||||
#endif
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
#import <HealthKit/HealthKit.h>
|
||||
#endif
|
||||
|
||||
@import HealthKit;
|
||||
@import MapKit;
|
||||
@import Contacts;
|
||||
|
||||
@@ -81,6 +83,8 @@ NSString *ORKQuestionTypeString(ORKQuestionType questionType) {
|
||||
SQT_CASE(Weight);
|
||||
SQT_CASE(Location);
|
||||
SQT_CASE(SES);
|
||||
SQT_CASE(Age);
|
||||
SQT_CASE(Year);
|
||||
}
|
||||
#undef SQT_CASE
|
||||
}
|
||||
@@ -95,6 +99,7 @@ static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattin
|
||||
NSMutableDictionary *_unitsTable;
|
||||
}
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
@synthesize healthStore=_healthStore;
|
||||
|
||||
+ (instancetype)sourceWithHealthStore:(HKHealthStore *)healthStore {
|
||||
@@ -203,8 +208,10 @@ static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattin
|
||||
[healthStore executeQuery:sampleQuery];
|
||||
});
|
||||
}
|
||||
#endif // ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
|
||||
- (void)fetchDefaultValueForAnswerFormat:(ORKAnswerFormat *)answerFormat handler:(void(^)(id defaultValue, NSError *error))handler {
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
HKObjectType *objectType = [answerFormat healthKitObjectType];
|
||||
BOOL handled = NO;
|
||||
if (objectType) {
|
||||
@@ -225,8 +232,12 @@ static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattin
|
||||
if (!handled) {
|
||||
handler(nil, nil);
|
||||
}
|
||||
#else
|
||||
handler(nil, nil);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
- (HKUnit *)defaultHealthKitUnitForAnswerFormat:(ORKAnswerFormat *)answerFormat {
|
||||
__block HKUnit *unit = [answerFormat healthKitUnit];
|
||||
HKObjectType *objectType = [answerFormat healthKitObjectType];
|
||||
@@ -268,10 +279,11 @@ static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattin
|
||||
[answerFormat setHealthKitUserUnit:healthKitDefault];
|
||||
}
|
||||
}
|
||||
#endif // ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
#endif // TARGET_OS_IOS
|
||||
|
||||
#pragma mark - ORKAnswerFormat
|
||||
|
||||
@@ -477,9 +489,11 @@ static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattin
|
||||
defaultValue:defaultValue];
|
||||
}
|
||||
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
+ (ORKLocationAnswerFormat *)locationAnswerFormat {
|
||||
return [ORKLocationAnswerFormat new];
|
||||
}
|
||||
#endif
|
||||
|
||||
+ (ORKSESAnswerFormat *)socioEconomicAnswerFormatWithTopRungText:(NSString *)topRungText
|
||||
bottomRungText:(NSString *)bottomRungText {
|
||||
@@ -502,6 +516,10 @@ static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattin
|
||||
return [[ORKTextChoiceAnswerFormat alloc] initWithStyle:style textChoices:textChoices];
|
||||
}
|
||||
|
||||
+ (ORKColorChoiceAnswerFormat *)choiceAnswerFormatWithStyle:(ORKChoiceAnswerStyle)style
|
||||
colorChoices:(NSArray<ORKColorChoice *> *)colorChoices {
|
||||
return [[ORKColorChoiceAnswerFormat alloc] initWithStyle:style colorChoices:colorChoices];
|
||||
}
|
||||
|
||||
- (void)validateParameters {
|
||||
}
|
||||
@@ -557,6 +575,7 @@ static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattin
|
||||
return NO;
|
||||
}
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
- (HKObjectType *)healthKitObjectType {
|
||||
return nil;
|
||||
}
|
||||
@@ -576,6 +595,7 @@ static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattin
|
||||
- (void)setHealthKitUserUnit:(HKUnit *)unit {
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
- (ORKQuestionType)questionType {
|
||||
return ORKQuestionTypeNone;
|
||||
@@ -1106,9 +1126,117 @@ static NSArray *ork_processTextChoices(NSArray<ORKTextChoice *> *textChoices) {
|
||||
return self.textChoices;
|
||||
}
|
||||
|
||||
- (BOOL)isAnswerInvalid:(id)answer {
|
||||
@try
|
||||
{
|
||||
[_helper selectedIndexesForAnswer: answer];
|
||||
return NO;
|
||||
} @catch(id anException) {
|
||||
ORK_Log_Error("%@ exception thrown for isAnswerInvalid: for answer:%@", anException, answer);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - ORKColorChoiceAnswerFormat
|
||||
|
||||
@interface ORKColorChoiceAnswerFormat () {
|
||||
|
||||
ORKChoiceAnswerFormatHelper *_helper;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation ORKColorChoiceAnswerFormat
|
||||
|
||||
+ (instancetype)new {
|
||||
ORKThrowMethodUnavailableException();
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
ORKThrowMethodUnavailableException();
|
||||
}
|
||||
|
||||
- (instancetype)initWithStyle:(ORKChoiceAnswerStyle)style
|
||||
colorChoices:(NSArray<ORKColorChoice *> *)colorChoices {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_style = style;
|
||||
_colorChoices = [colorChoices copy];
|
||||
_helper = [[ORKChoiceAnswerFormatHelper alloc] initWithAnswerFormat:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)validateParameters {
|
||||
[super validateParameters];
|
||||
}
|
||||
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
ORKColorChoiceAnswerFormat *answerFormat = [[[self class] allocWithZone:zone] initWithStyle:_style
|
||||
colorChoices:[_colorChoices copy]];
|
||||
return answerFormat;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
BOOL isParentSame = [super isEqual:object];
|
||||
|
||||
__typeof(self) castObject = object;
|
||||
return (isParentSame &&
|
||||
ORKEqualObjects(_colorChoices, castObject.colorChoices) &&
|
||||
(_style == castObject.style));
|
||||
}
|
||||
|
||||
- (NSUInteger)hash {
|
||||
return super.hash ^ _colorChoices.hash ^ _style;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if (self) {
|
||||
ORK_DECODE_OBJ_ARRAY(aDecoder, colorChoices, ORKColorChoice);
|
||||
ORK_DECODE_ENUM(aDecoder, style);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[super encodeWithCoder:aCoder];
|
||||
ORK_ENCODE_OBJ(aCoder, colorChoices);
|
||||
ORK_ENCODE_ENUM(aCoder, style);
|
||||
|
||||
}
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (ORKQuestionType)questionType {
|
||||
return (_style == ORKChoiceAnswerStyleSingleChoice) ? ORKQuestionTypeSingleChoice : ORKQuestionTypeMultipleChoice;
|
||||
}
|
||||
|
||||
- (Class)questionResultClass {
|
||||
return [ORKChoiceQuestionResult class];
|
||||
}
|
||||
|
||||
- (NSString *)stringForAnswer:(id)answer {
|
||||
return [_helper stringForChoiceAnswer:answer];
|
||||
}
|
||||
|
||||
- (BOOL)shouldShowDontKnowButton {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSArray *)choices {
|
||||
return self.colorChoices;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - ORKTextChoice
|
||||
@@ -1270,6 +1398,93 @@ NSArray<Class> *ORKAllowableValueClasses(void) {
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - ORKColorChoice
|
||||
|
||||
@implementation ORKColorChoice
|
||||
|
||||
+ (instancetype)new {
|
||||
ORKThrowMethodUnavailableException();
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
ORKThrowMethodUnavailableException();
|
||||
}
|
||||
|
||||
- (instancetype)initWithColor:(UIColor *)color
|
||||
text:(NSString *)text
|
||||
detailText:(NSString *)detailText
|
||||
value:(NSObject<NSCopying,NSSecureCoding> *)value
|
||||
exclusive:(BOOL)exclusive {
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
_color = [color copy];
|
||||
_text = [text copy];
|
||||
_detailText = [detailText copy];
|
||||
_value = [value copy];
|
||||
_exclusive = exclusive;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithColor:(UIColor *)color
|
||||
text:(NSString *)text
|
||||
detailText:(NSString *)detailText
|
||||
value:(NSObject<NSCopying,NSSecureCoding> *)value {
|
||||
return [self initWithColor:color text:text detailText:detailText value:value exclusive:NO];
|
||||
}
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
if ([self class] != [object class]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
__typeof(self) castObject = object;
|
||||
return (ORKEqualObjects(self.text, castObject.text)
|
||||
&& ORKEqualObjects(self.detailText, castObject.detailText)
|
||||
&& ORKEqualObjects(self.value, castObject.value)
|
||||
&& ORKEqualObjects(self.color, castObject.color)
|
||||
&& self.exclusive == castObject.exclusive);
|
||||
}
|
||||
|
||||
- (NSUInteger)hash {
|
||||
return _text.hash ^ _detailText.hash ^ _value.hash ^ _color.hash;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, text, NSString);
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, color, UIColor);
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, detailText, NSString);
|
||||
ORK_DECODE_OBJ_CLASSES(aDecoder, value, ORKAllowableValueClasses());
|
||||
ORK_DECODE_BOOL(aDecoder, exclusive);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
ORK_ENCODE_OBJ(aCoder, text);
|
||||
ORK_ENCODE_OBJ(aCoder, color);
|
||||
ORK_ENCODE_OBJ(aCoder, detailText);
|
||||
ORK_ENCODE_OBJ(aCoder, value);
|
||||
ORK_ENCODE_BOOL(aCoder, exclusive);
|
||||
}
|
||||
|
||||
- (BOOL)shouldShowDontKnowButton {
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - ORKTextChoiceOther
|
||||
@@ -2916,6 +3131,7 @@ NSArray<Class> *ORKAllowableValueClasses(void) {
|
||||
answerFormat->_spellCheckingType = _spellCheckingType;
|
||||
answerFormat->_keyboardType = _keyboardType;
|
||||
answerFormat->_textContentType = _textContentType;
|
||||
|
||||
if (@available(iOS 12.0, *)) {
|
||||
answerFormat->_passwordRules = _passwordRules;
|
||||
}
|
||||
@@ -2992,6 +3208,7 @@ NSArray<Class> *ORKAllowableValueClasses(void) {
|
||||
answerFormat->_keyboardType = _keyboardType;
|
||||
answerFormat->_autocapitalizationType = _autocapitalizationType;
|
||||
answerFormat->_textContentType = _textContentType;
|
||||
|
||||
if (@available(iOS 12.0, *)) {
|
||||
answerFormat->_passwordRules = _passwordRules;
|
||||
}
|
||||
@@ -3572,6 +3789,237 @@ static NSString *const kSecureTextEntryEscapeString = @"*";
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - ORKAgeAnswerFormat
|
||||
|
||||
static const NSInteger ORKAgeAnswerDefaultMinAge = 1;
|
||||
static const NSInteger ORKAgeAnswerDefaultMaxAge = 125;
|
||||
|
||||
@implementation ORKAgeAnswerFormat
|
||||
|
||||
- (Class)questionResultClass {
|
||||
return [ORKNumericQuestionResult class];
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
|
||||
return [self initWithMinimumAge:ORKAgeAnswerDefaultMinAge
|
||||
maximumAge:ORKAgeAnswerDefaultMaxAge
|
||||
minimumAgeCustomText:nil
|
||||
maximumAgeCustomText:nil
|
||||
showYear:NO
|
||||
useYearForResult:NO
|
||||
defaultValue:ORKAgeAnswerDefaultMinAge];
|
||||
}
|
||||
|
||||
- (instancetype)initWithMinimumAge:(NSInteger)minimumAge maximumAge:(NSInteger)maximumAge {
|
||||
return [self initWithMinimumAge:minimumAge
|
||||
maximumAge:maximumAge
|
||||
minimumAgeCustomText:nil
|
||||
maximumAgeCustomText:nil
|
||||
showYear:NO
|
||||
useYearForResult:NO
|
||||
defaultValue:minimumAge];
|
||||
|
||||
}
|
||||
|
||||
- (instancetype)initWithMinimumAge:(NSInteger)minimumAge
|
||||
maximumAge:(NSInteger)maximumAge
|
||||
minimumAgeCustomText:(nullable NSString *)minimumAgeCustomText
|
||||
maximumAgeCustomText:(nullable NSString *)maximumAgeCustomText
|
||||
showYear:(BOOL)showYear
|
||||
useYearForResult:(BOOL)useYearForResult
|
||||
defaultValue:(NSInteger)defaultValue {
|
||||
return [self initWithMinimumAge:minimumAge
|
||||
maximumAge:maximumAge
|
||||
minimumAgeCustomText:minimumAgeCustomText
|
||||
maximumAgeCustomText:maximumAgeCustomText
|
||||
showYear:showYear
|
||||
useYearForResult:useYearForResult
|
||||
treatMinAgeAsRange:NO
|
||||
treatMaxAgeAsRange:NO
|
||||
defaultValue:defaultValue];
|
||||
}
|
||||
|
||||
- (instancetype)initWithMinimumAge:(NSInteger)minimumAge
|
||||
maximumAge:(NSInteger)maximumAge
|
||||
minimumAgeCustomText:(nullable NSString *)minimumAgeCustomText
|
||||
maximumAgeCustomText:(nullable NSString *)maximumAgeCustomText
|
||||
showYear:(BOOL)showYear
|
||||
useYearForResult:(BOOL)useYearForResult
|
||||
treatMinAgeAsRange:(BOOL)treatMinAgeAsRange
|
||||
treatMaxAgeAsRange:(BOOL)treatMaxAgeAsRange
|
||||
defaultValue:(NSInteger)defaultValue {
|
||||
if (minimumAge < 0) {
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException
|
||||
reason: [NSString stringWithFormat:@"minimumAge must be greater than 0. (%li) - (%li)", minimumAge, maximumAge]
|
||||
userInfo:nil];
|
||||
|
||||
}
|
||||
|
||||
if (maximumAge > 150) {
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException
|
||||
reason:@"maximumAge must be lower than 150."
|
||||
userInfo:nil];
|
||||
}
|
||||
|
||||
if (minimumAge >= maximumAge) {
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException
|
||||
reason:[NSString stringWithFormat:@"minimumAge must be less than maximumAge. (%li) - (%li)", minimumAge, maximumAge]
|
||||
userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
_minimumAge = minimumAge;
|
||||
_maximumAge = maximumAge;
|
||||
_minimumAgeCustomText = [minimumAgeCustomText copy];
|
||||
_maximumAgeCustomText = [maximumAgeCustomText copy];
|
||||
_showYear = showYear;
|
||||
_useYearForResult = useYearForResult;
|
||||
_treatMinAgeAsRange = treatMinAgeAsRange;
|
||||
_treatMaxAgeAsRange = treatMaxAgeAsRange;
|
||||
_relativeYear = [self currentYear];
|
||||
_defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (int)minimumAgeSentinelValue {
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ (int)maximumAgeSentinelValue {
|
||||
return -2;
|
||||
}
|
||||
|
||||
- (NSInteger)currentYear {
|
||||
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
|
||||
NSDateComponents *components = [calendar components:NSCalendarUnitYear fromDate:[NSDate date]];
|
||||
return [components year];
|
||||
}
|
||||
|
||||
- (NSString *)stringForAnswer:(id)answer {
|
||||
NSString *answerString = nil;
|
||||
|
||||
if (!ORKIsAnswerEmpty(answer)) {
|
||||
NSNumberFormatter *formatter = ORKDecimalNumberFormatter();
|
||||
answerString = [formatter stringFromNumber:(NSNumber *)answer];
|
||||
}
|
||||
|
||||
if (answerString) {
|
||||
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
|
||||
NSDateComponents *components = [calendar components:NSCalendarUnitYear fromDate:[NSDate date]];
|
||||
NSInteger currentYear = [components year];
|
||||
|
||||
int maxYear = currentYear - _minimumAge;
|
||||
int minYear = currentYear - _maximumAge;
|
||||
|
||||
NSString *minAgeText = _minimumAgeCustomText ? : [NSString stringWithFormat:ORKLocalizedString(@"AGEPICKER_OR_YOUNGER", ""), (long)_minimumAge];
|
||||
NSString *maxAgeText = _maximumAgeCustomText ? : [NSString stringWithFormat:ORKLocalizedString(@"AGEPICKER_OR_OLDER", ""), (long)_maximumAge];
|
||||
|
||||
int value = [answerString intValue];
|
||||
|
||||
if (value < 0) {
|
||||
// pass back necessary text if sentinel value is selected
|
||||
answerString = value == [ORKAgeAnswerFormat minimumAgeSentinelValue] ? minAgeText : maxAgeText;
|
||||
} else if (_useYearForResult) {
|
||||
// pass back necessary text if min or max year is selected
|
||||
if ((value >= maxYear || value <= minYear)) {
|
||||
answerString = value <= minYear ? maxAgeText : minAgeText;
|
||||
}
|
||||
} else if ((value == _minimumAge && _minimumAgeCustomText ) || (value == _maximumAge && _maximumAgeCustomText)) {
|
||||
answerString = value == _minimumAge ? _minimumAgeCustomText : _maximumAgeCustomText;
|
||||
} else if ((value == minYear && _minimumAgeCustomText) || (value == maxYear && _maximumAgeCustomText)) {
|
||||
answerString = value == minYear ? _minimumAgeCustomText : _maximumAgeCustomText;
|
||||
}
|
||||
}
|
||||
|
||||
return answerString;
|
||||
}
|
||||
|
||||
- (ORKQuestionType)questionType {
|
||||
return _useYearForResult ? ORKQuestionTypeYear : ORKQuestionTypeAge;
|
||||
}
|
||||
|
||||
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
ORKAgeAnswerFormat *ageAnswerFormat = [super copyWithZone:zone];
|
||||
ageAnswerFormat->_minimumAge = _minimumAge;
|
||||
ageAnswerFormat->_maximumAge = _maximumAge;
|
||||
ageAnswerFormat->_minimumAgeCustomText = [_minimumAgeCustomText copy];
|
||||
ageAnswerFormat->_maximumAgeCustomText = [_maximumAgeCustomText copy];
|
||||
ageAnswerFormat->_showYear = _showYear;
|
||||
ageAnswerFormat->_useYearForResult = _useYearForResult;
|
||||
ageAnswerFormat->_treatMinAgeAsRange = _treatMinAgeAsRange;
|
||||
ageAnswerFormat->_treatMaxAgeAsRange = _treatMaxAgeAsRange;
|
||||
ageAnswerFormat->_relativeYear = _relativeYear;
|
||||
ageAnswerFormat->_defaultValue = _defaultValue;
|
||||
return ageAnswerFormat;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
BOOL isParentSame = [super isEqual:object];
|
||||
|
||||
__typeof(self) castObject = object;
|
||||
return (isParentSame &&
|
||||
(_minimumAge == castObject->_minimumAge) &&
|
||||
(_maximumAge == castObject->_maximumAge) &&
|
||||
(_relativeYear == castObject->_relativeYear) &&
|
||||
ORKEqualObjects(_minimumAgeCustomText, castObject->_minimumAgeCustomText) &&
|
||||
ORKEqualObjects(_maximumAgeCustomText, castObject->_maximumAgeCustomText) &&
|
||||
(_showYear == castObject->_showYear) &&
|
||||
(_useYearForResult == castObject->_useYearForResult) &&
|
||||
(_treatMinAgeAsRange == castObject->_treatMinAgeAsRange) &&
|
||||
(_treatMaxAgeAsRange == castObject->_treatMaxAgeAsRange) &&
|
||||
(_defaultValue == castObject->_defaultValue));
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if (self) {
|
||||
ORK_DECODE_INTEGER(aDecoder, minimumAge);
|
||||
ORK_DECODE_INTEGER(aDecoder, maximumAge);
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, minimumAgeCustomText, NSString);
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, maximumAgeCustomText, NSString);
|
||||
ORK_DECODE_BOOL(aDecoder, showYear);
|
||||
ORK_DECODE_BOOL(aDecoder, useYearForResult);
|
||||
ORK_DECODE_BOOL(aDecoder, treatMinAgeAsRange);
|
||||
ORK_DECODE_BOOL(aDecoder, treatMaxAgeAsRange);
|
||||
ORK_DECODE_BOOL(aDecoder, useYearForResult);
|
||||
ORK_DECODE_INTEGER(aDecoder, defaultValue);
|
||||
ORK_DECODE_INTEGER(aDecoder, relativeYear);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[super encodeWithCoder:aCoder];
|
||||
ORK_ENCODE_INTEGER(aCoder, minimumAge);
|
||||
ORK_ENCODE_INTEGER(aCoder, maximumAge);
|
||||
ORK_ENCODE_OBJ(aCoder, minimumAgeCustomText);
|
||||
ORK_ENCODE_OBJ(aCoder, maximumAgeCustomText);
|
||||
ORK_ENCODE_BOOL(aCoder, showYear);
|
||||
ORK_ENCODE_BOOL(aCoder, useYearForResult);
|
||||
ORK_ENCODE_BOOL(aCoder, treatMinAgeAsRange);
|
||||
ORK_ENCODE_BOOL(aCoder, treatMaxAgeAsRange);
|
||||
ORK_ENCODE_INTEGER(aCoder, defaultValue);
|
||||
ORK_ENCODE_INTEGER(aCoder, relativeYear);
|
||||
}
|
||||
|
||||
- (NSUInteger)hash {
|
||||
return super.hash ^ _minimumAgeCustomText.hash ^ _maximumAgeCustomText.hash ^ _minimumAge ^ _maximumAge ^ _showYear ^ _useYearForResult ^ _treatMinAgeAsRange ^ _treatMaxAgeAsRange ^ _relativeYear ^ _defaultValue;
|
||||
}
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
#pragma mark - ORKLocationAnswerFormat
|
||||
@implementation ORKLocationAnswerFormat
|
||||
|
||||
@@ -3642,6 +4090,7 @@ static NSString *const kSecureTextEntryEscapeString = @"*";
|
||||
}
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
||||
#pragma mark ORKSESAnswerFormat
|
||||
|
||||
|
||||
@@ -29,7 +29,10 @@
|
||||
*/
|
||||
|
||||
|
||||
@import HealthKit;
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
#import <HealthKit/HealthKit.h>
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#import <ResearchKit/ORKAnswerFormat_Private.h>
|
||||
#import <ResearchKit/ORKChoiceAnswerFormatHelper.h>
|
||||
@@ -41,9 +44,11 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
BOOL ORKIsAnswerEmpty(_Nullable id answer);
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
NSString *ORKHKBiologicalSexString(HKBiologicalSex biologicalSex);
|
||||
NSString *ORKHKBloodTypeString(HKBloodType bloodType);
|
||||
#endif
|
||||
#endif // ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
#endif // TARGET_OS_IOS
|
||||
NSString *ORKQuestionTypeString(ORKQuestionType questionType);
|
||||
|
||||
// Need to mark these as designated initializers to avoid warnings once we designate the others.
|
||||
@@ -69,6 +74,7 @@ ORK_DESIGNATE_CODING_AND_SERIALIZATION_INITIALIZERS(ORKTextAnswerFormat)
|
||||
ORK_DESIGNATE_CODING_AND_SERIALIZATION_INITIALIZERS(ORKTimeIntervalAnswerFormat)
|
||||
ORK_DESIGNATE_CODING_AND_SERIALIZATION_INITIALIZERS(ORKHeightAnswerFormat)
|
||||
ORK_DESIGNATE_CODING_AND_SERIALIZATION_INITIALIZERS(ORKWeightAnswerFormat)
|
||||
ORK_DESIGNATE_CODING_AND_SERIALIZATION_INITIALIZERS(ORKAgeAnswerFormat)
|
||||
#endif
|
||||
ORK_DESIGNATE_CODING_AND_SERIALIZATION_INITIALIZERS(ORKTextChoiceAnswerFormat)
|
||||
ORK_DESIGNATE_CODING_AND_SERIALIZATION_INITIALIZERS(ORKTextChoice)
|
||||
@@ -83,13 +89,15 @@ ORK_DESIGNATE_CODING_AND_SERIALIZATION_INITIALIZERS(ORKTextChoice)
|
||||
#if TARGET_OS_IOS
|
||||
- (BOOL)isHealthKitAnswerFormat;
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
- (nullable HKObjectType *)healthKitObjectType;
|
||||
- (nullable HKObjectType *)healthKitObjectTypeForAuthorization;
|
||||
|
||||
@property (nonatomic, strong, readonly, nullable) HKUnit *healthKitUnit;
|
||||
|
||||
@property (nonatomic, strong, nullable) HKUnit *healthKitUserUnit;
|
||||
#endif
|
||||
#endif // ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
#endif // TARGET_OS_IOS
|
||||
|
||||
- (nullable NSString *)localizedInvalidValueStringWithAnswerString:(nullable NSString *)text;
|
||||
|
||||
@@ -254,16 +262,16 @@ NSArray<Class> *ORKAllowableValueClasses(void);
|
||||
|
||||
@interface ORKAnswerDefaultSource : NSObject
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
+ (instancetype)sourceWithHealthStore:(HKHealthStore *)healthStore;
|
||||
- (instancetype)initWithHealthStore:(HKHealthStore *)healthStore NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@property (nonatomic, strong, readonly, nullable) HKHealthStore *healthStore;
|
||||
|
||||
- (void)fetchDefaultValueForAnswerFormat:(nullable ORKAnswerFormat *)answerFormat handler:(void(^)(id defaultValue, NSError *error))handler;
|
||||
|
||||
- (nullable HKUnit *)defaultHealthKitUnitForAnswerFormat:(ORKAnswerFormat *)answerFormat;
|
||||
- (void)updateHealthKitUnitForAnswerFormat:(ORKAnswerFormat *)answerFormat force:(BOOL)force;
|
||||
#endif
|
||||
|
||||
- (void)fetchDefaultValueForAnswerFormat:(nullable ORKAnswerFormat *)answerFormat handler:(void(^)(id defaultValue, NSError *error))handler;
|
||||
@end
|
||||
|
||||
@interface ORKTextChoiceOther()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -61,6 +61,10 @@
|
||||
}
|
||||
|
||||
- (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 @@
|
||||
self.image = image;
|
||||
self.useCardStyle = useCardStyle;
|
||||
self.useSecondaryColor = NO;
|
||||
self.alignImageToTop = alignImageToTop;
|
||||
}
|
||||
[self validateParameters];
|
||||
return self;
|
||||
@@ -127,6 +132,7 @@
|
||||
bodyItem->_image = [self.image copy];
|
||||
bodyItem->_useCardStyle = self.useCardStyle;
|
||||
bodyItem->_useSecondaryColor = self.useSecondaryColor;
|
||||
bodyItem->_alignImageToTop = self.alignImageToTop;
|
||||
return bodyItem;
|
||||
}
|
||||
|
||||
@@ -146,7 +152,8 @@
|
||||
&& (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
|
||||
|
||||
@@ -28,14 +28,14 @@
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
@import Foundation;
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class ORKAnswerFormat;
|
||||
@class ORKImageChoice;
|
||||
@class ORKTextChoice;
|
||||
|
||||
@class ORKColorChoice;
|
||||
|
||||
@protocol ORKAnswerOption;
|
||||
|
||||
@@ -74,6 +74,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
- (nullable ORKImageChoice *)imageChoiceAtIndex:(NSUInteger)index;
|
||||
|
||||
- (nullable ORKColorChoice *)colorChoiceAtIndex:(NSUInteger)index;
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
||||
@@ -69,7 +69,10 @@
|
||||
return option && [option isKindOfClass:[ORKImageChoice class]] ? (ORKImageChoice *) option : nil;
|
||||
}
|
||||
|
||||
|
||||
- (ORKColorChoice *)colorChoiceAtIndex:(NSUInteger)index {
|
||||
id<ORKAnswerOption> option = [self answerOptionAtIndex:index];
|
||||
return option && [option isKindOfClass:[ORKColorChoice class]] ? (ORKColorChoice *) option : nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (ORKTextChoice *)textChoiceAtIndex:(NSUInteger)index {
|
||||
@@ -138,6 +141,8 @@
|
||||
|
||||
for (id answerValue in (NSArray *)answer) {
|
||||
id<ORKAnswerOption> matchedChoice = nil;
|
||||
BOOL isTextChoiceOtherResult = [self _isTextChoiceOtherResult:answerValue choices:_choices];
|
||||
|
||||
for ( id<ORKAnswerOption> choice in _choices) {
|
||||
#if TARGET_OS_IOS
|
||||
if ([choice isKindOfClass:[ORKTextChoiceOther class]]) {
|
||||
@@ -148,7 +153,12 @@
|
||||
} else if (textChoiceOther.textViewInputOptional && textChoiceOther.textViewText.length <= 0 && [textChoiceOther.value isEqual:answerValue]) {
|
||||
matchedChoice = choice;
|
||||
break;
|
||||
} else if (isTextChoiceOtherResult) {
|
||||
textChoiceOther.textViewText = answerValue;
|
||||
matchedChoice = choice;
|
||||
break;
|
||||
}
|
||||
|
||||
} else if ([choice.value isEqual:answerValue]) {
|
||||
matchedChoice = choice;
|
||||
break;
|
||||
@@ -191,6 +201,20 @@
|
||||
|
||||
}
|
||||
|
||||
- (BOOL)_isTextChoiceOtherResult:(id)answerValue choices:(NSArray *)choices {
|
||||
if (answerValue == nil) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
for (id<ORKAnswerOption> choice in _choices) {
|
||||
if ([choice.value isEqual:answerValue]){
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *)stringForChoiceAnswer:(id)answer {
|
||||
NSMutableArray<NSString *> *answerStrings = [[NSMutableArray alloc] init];
|
||||
NSArray *indexes = [self selectedIndexesForAnswer:answer];
|
||||
|
||||
@@ -30,9 +30,11 @@
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <HealthKit/HealthKit.h>
|
||||
#import <ResearchKit/ORKDefines.h>
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
#import <HealthKit/HealthKit.h>
|
||||
#endif
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@@ -85,6 +87,8 @@ ORK_CLASS_AVAILABLE
|
||||
It cannot be initiated directly.
|
||||
Use `addHealthCollectorWithSampleType:`to add one to a `ORKDataCollectionManager`.
|
||||
*/
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKHealthCollector : ORKCollector
|
||||
|
||||
@@ -146,7 +150,7 @@ ORK_CLASS_AVAILABLE
|
||||
@property (copy, readonly) HKQueryAnchor *lastAnchor;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
An object that collects CMMotionActivity.
|
||||
|
||||
@@ -112,7 +112,7 @@ static NSString *const ItemIdentifierFormatWithTwoPlaceholders = @"org.researchk
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
@implementation ORKHealthCollector : ORKCollector
|
||||
|
||||
- (instancetype)initWithSampleType:(HKSampleType*)sampleType unit:(HKUnit*)unit startDate:(NSDate*)startDate {
|
||||
@@ -288,7 +288,7 @@ static NSString *const ItemIdentifierFormatWithTwoPlaceholders = @"org.researchk
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
@implementation ORKMotionActivityCollector : ORKCollector
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
@protocol ORKHealthCollectable <NSObject>
|
||||
|
||||
- (HKSampleType *)sampleType;
|
||||
@@ -71,7 +71,7 @@
|
||||
@property (copy) HKQueryAnchor *lastAnchor;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
@interface ORKMotionActivityCollector()
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
Copyright (c) 2023, Apple Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <ResearchKit/ORKTypes.h>
|
||||
|
||||
@class ORKTaskResult;
|
||||
@class ORKHealthCondition;
|
||||
@class ORKFormItem;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
The base object for configuring the displayed health conditions
|
||||
for the family history step.
|
||||
*/
|
||||
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKConditionStepConfiguration : NSObject <NSSecureCoding, NSCopying>
|
||||
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Creates a new conditions step configuration.
|
||||
|
||||
This method is the primary designated initializer.
|
||||
|
||||
@param stepIdentifier The identifier attached to the form step that displays the health conditions.
|
||||
@param conditionsFormItemIdentifier The identifier attached to the form item used from the health conditions list.
|
||||
@param conditions List of health conditions displayed to participants.
|
||||
@param formItems List of form items that are presented below the health conditions text choice. This is optional.
|
||||
*/
|
||||
- (instancetype)initWithStepIdentifier:(NSString *)stepIdentifier
|
||||
conditionsFormItemIdentifier:(NSString *)conditionsFormItemIdentifier
|
||||
conditions:(NSArray<ORKHealthCondition *> *)conditions
|
||||
formItems:(NSArray<ORKFormItem *> *)formItems NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@property (nonatomic, readonly, copy) NSString *stepIdentifier;
|
||||
@property (nonatomic, readonly, copy) NSString *conditionsFormItemIdentifier;
|
||||
@property (nonatomic, readonly, copy) NSArray<ORKHealthCondition *> *conditions;
|
||||
@property (nonatomic, copy) NSArray<ORKFormItem *> *formItems;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
Copyright (c) 2023, 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 "ORKConditionStepConfiguration.h"
|
||||
|
||||
#import "ORKCollectionResult.h"
|
||||
#import "ORKFormStep.h"
|
||||
#import "ORKHealthCondition.h"
|
||||
#import "ORKHelpers_Internal.h"
|
||||
|
||||
|
||||
@implementation ORKConditionStepConfiguration
|
||||
|
||||
- (instancetype)initWithStepIdentifier:(NSString *)stepIdentifier
|
||||
conditionsFormItemIdentifier:(NSString *)conditionsFormItemIdentifier
|
||||
conditions:(NSArray<ORKHealthCondition *> *)conditions
|
||||
formItems:(nonnull NSArray<ORKFormItem *> *)formItems {
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
_stepIdentifier = [stepIdentifier copy];
|
||||
_conditionsFormItemIdentifier = [conditionsFormItemIdentifier copy];
|
||||
_conditions = [conditions copy];
|
||||
_formItems = [formItems copy];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
ORK_ENCODE_OBJ(aCoder, stepIdentifier);
|
||||
ORK_ENCODE_OBJ(aCoder, conditionsFormItemIdentifier);
|
||||
ORK_ENCODE_OBJ(aCoder, conditions);
|
||||
ORK_ENCODE_OBJ(aCoder, formItems);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, stepIdentifier, NSString);
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, conditionsFormItemIdentifier, NSString);
|
||||
ORK_DECODE_OBJ_ARRAY(aDecoder, conditions, ORKHealthCondition);
|
||||
ORK_DECODE_OBJ_ARRAY(aDecoder, formItems, ORKFormItem);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)copyWithZone:(nullable NSZone *)zone {
|
||||
ORKConditionStepConfiguration *conditionStepConfiguration = [[[self class] alloc] init];
|
||||
conditionStepConfiguration->_stepIdentifier = [_stepIdentifier copy];
|
||||
conditionStepConfiguration->_conditionsFormItemIdentifier = [_conditionsFormItemIdentifier copy];
|
||||
conditionStepConfiguration->_conditions = [_conditions copy];
|
||||
conditionStepConfiguration->_formItems = [_formItems copy];
|
||||
|
||||
return conditionStepConfiguration;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
if ([self class] != [object class]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
__typeof(self) castObject = object;
|
||||
return (ORKEqualObjects(_stepIdentifier, castObject->_stepIdentifier)
|
||||
&& ORKEqualObjects(_conditionsFormItemIdentifier, castObject->_conditionsFormItemIdentifier)
|
||||
&& ORKEqualObjects(_conditions, castObject->_conditions)
|
||||
&& ORKEqualObjects(_formItems, castObject->_formItems));
|
||||
}
|
||||
|
||||
- (NSUInteger)hash {
|
||||
return super.hash ^ _stepIdentifier.hash ^ _conditionsFormItemIdentifier.hash ^ _conditions.hash ^ _formItems.hash;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -60,6 +60,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
If NO is returned or this method is not implemented, the manager will stop the collection for the collector and repeat this same collection next time,
|
||||
until the data is accepted.
|
||||
*/
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
- (BOOL)healthCollector:(ORKHealthCollector *)collector didCollectSamples:(NSArray<HKSample *> *)samples;
|
||||
|
||||
/**
|
||||
@@ -73,7 +74,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
until the data is accepted.
|
||||
*/
|
||||
- (BOOL)healthCorrelationCollector:(ORKHealthCorrelationCollector *)collector didCollectCorrelations:(NSArray<HKCorrelation *> *)correlations;
|
||||
|
||||
#endif
|
||||
/**
|
||||
Method for delivering the collected motion activities.
|
||||
|
||||
@@ -145,6 +146,7 @@ ORK_CLASS_AVAILABLE
|
||||
|
||||
@return Initiated health collector.
|
||||
*/
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
- (ORKHealthCollector *)addHealthCollectorWithSampleType:(HKSampleType *)sampleType
|
||||
unit:(HKUnit *)unit
|
||||
startDate:(NSDate *)startDate
|
||||
@@ -166,7 +168,7 @@ ORK_CLASS_AVAILABLE
|
||||
units:(NSArray<HKUnit *> *)units
|
||||
startDate:(NSDate *)startDate
|
||||
error:(NSError * _Nullable *)error;
|
||||
|
||||
#endif
|
||||
/**
|
||||
Add a collector for motion activity.
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
#import "ORKHelpers_Internal.h"
|
||||
#import <HealthKit/HealthKit.h>
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
#import <HealthKit/HealthKit.h>
|
||||
#endif
|
||||
|
||||
static NSString *const ORKDataCollectionPersistenceFileName = @".dataCollection.ork.data";
|
||||
|
||||
@@ -43,8 +46,10 @@ static NSString *const ORKDataCollectionPersistenceFileName = @".dataCollection
|
||||
NSOperationQueue *_operationQueue;
|
||||
NSString * _Nonnull _managedDirectory;
|
||||
NSArray<ORKCollector *> *_collectors;
|
||||
HKHealthStore *_healthStore;
|
||||
CMMotionActivityManager *_activityManager;
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
HKHealthStore *_healthStore;
|
||||
#endif
|
||||
NSMutableArray<HKObserverQueryCompletionHandler> *_completionHandlers;
|
||||
}
|
||||
|
||||
@@ -117,12 +122,14 @@ static inline void dispatch_sync_if_not_on_queue(dispatch_queue_t queue, dispatc
|
||||
});
|
||||
}
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
- (HKHealthStore *)healthStore {
|
||||
if (!_healthStore && [HKHealthStore isHealthDataAvailable]){
|
||||
_healthStore = [[HKHealthStore alloc] init];
|
||||
}
|
||||
return _healthStore;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (CMMotionActivityManager *)activityManager {
|
||||
if (!_activityManager && [CMMotionActivityManager isActivityAvailable]) {
|
||||
@@ -167,6 +174,7 @@ static inline void dispatch_sync_if_not_on_queue(dispatch_queue_t queue, dispatc
|
||||
_collectors = [collectors copy];
|
||||
}
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
- (ORKHealthCollector *)addHealthCollectorWithSampleType:(HKSampleType*)sampleType unit:(HKUnit *)unit startDate:(NSDate *)startDate error:(NSError**)error {
|
||||
|
||||
if (!sampleType) {
|
||||
@@ -219,6 +227,7 @@ static inline void dispatch_sync_if_not_on_queue(dispatch_queue_t queue, dispatc
|
||||
|
||||
return healthCorrelationCollector;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (ORKMotionActivityCollector *)addMotionActivityCollectorWithStartDate:(NSDate *)startDate
|
||||
error:(NSError* __autoreleasing *)error {
|
||||
@@ -319,13 +328,16 @@ static inline void dispatch_sync_if_not_on_queue(dispatch_queue_t queue, dispatc
|
||||
if (_delegate && [_delegate respondsToSelector:@selector(dataCollectionManagerDidCompleteCollection:)]) {
|
||||
[_delegate dataCollectionManagerDidCompleteCollection:self];
|
||||
}
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
for (HKObserverQueryCompletionHandler handler in _completionHandlers) {
|
||||
handler();
|
||||
}
|
||||
[_completionHandlers removeAllObjects];
|
||||
|
||||
return NO;
|
||||
#else
|
||||
return NO;
|
||||
#endif
|
||||
}];
|
||||
}];
|
||||
|
||||
@@ -340,7 +352,6 @@ static inline void dispatch_sync_if_not_on_queue(dispatch_queue_t queue, dispatc
|
||||
// No need to persist collectors
|
||||
return NO;
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -35,7 +35,9 @@
|
||||
|
||||
@interface ORKDataCollectionManager ()
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
@property (nonatomic, strong, readonly) HKHealthStore *healthStore;
|
||||
#endif
|
||||
|
||||
@property (nonatomic, strong, readonly) CMMotionActivityManager *activityManager;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
*/
|
||||
|
||||
|
||||
@import Foundation;
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <ResearchKit/ORKTypes.h>
|
||||
|
||||
|
||||
|
||||
@@ -32,9 +32,6 @@
|
||||
#import "ORKDataLogger.h"
|
||||
|
||||
#import "ORKHelpers_Internal.h"
|
||||
#import "CMMotionActivity+ORKJSONDictionary.h"
|
||||
#import "HKSample+ORKJSONDictionary.h"
|
||||
|
||||
#include <sys/xattr.h>
|
||||
|
||||
|
||||
|
||||
@@ -40,14 +40,5 @@
|
||||
|
||||
#define ORK_IOS_10_WATCHOS_3_AVAILABLE (NSClassFromString(@"HKWorkoutConfiguration") != nil)
|
||||
|
||||
// Some CLLocationManager API calls would trigger authorization to use location. The presence of those
|
||||
// API calls in ResearchKit **at compile time** mean apps that link ResearchKit also need Info.plist entries
|
||||
// for NSLocationAlwaysAndWhenInUseUsageDescription and NSLocationWhenInUseUsageDescription.
|
||||
// If your app doesn't use ORKLocationRecorder and doesn't specify these Info.plist strings, disable
|
||||
// ResearchKit's CLLocationManager authorization
|
||||
#ifndef ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
#define ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION 1
|
||||
#endif
|
||||
|
||||
#define ORK_TO_BE_DEPRECATED(message) \
|
||||
__deprecated_msg(message)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
*/
|
||||
|
||||
|
||||
@import Foundation;
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#import <ResearchKit/ORKDefines.h>
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright (c) 2023, 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/ORKResult.h>
|
||||
|
||||
@class ORKRelatedPerson;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
A result object produced by the family history step.
|
||||
*/
|
||||
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKFamilyHistoryResult : ORKResult
|
||||
|
||||
@property (nonatomic, nullable, copy) NSArray<ORKRelatedPerson *> *relatedPersons;
|
||||
@property (nonatomic, nullable, copy) NSArray<NSString *> *displayedConditions;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright (c) 2023, 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 "ORKFamilyHistoryResult.h"
|
||||
|
||||
#import "ORKHelpers_Internal.h"
|
||||
#import "ORKRelatedPerson.h"
|
||||
#import "ORKResult_Private.h"
|
||||
|
||||
|
||||
@implementation ORKFamilyHistoryResult
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[super encodeWithCoder:aCoder];
|
||||
ORK_ENCODE_OBJ(aCoder, relatedPersons);
|
||||
ORK_ENCODE_OBJ(aCoder, displayedConditions);
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if (self) {
|
||||
ORK_DECODE_OBJ_ARRAY(aDecoder, relatedPersons, ORKRelatedPerson);
|
||||
ORK_DECODE_OBJ_ARRAY(aDecoder, displayedConditions, NSString);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
BOOL isParentSame = [super isEqual:object];
|
||||
|
||||
__typeof(self) castObject = object;
|
||||
return (isParentSame &&
|
||||
ORKEqualObjects(self.relatedPersons, castObject.relatedPersons) &&
|
||||
ORKEqualObjects(self.displayedConditions, castObject.displayedConditions));
|
||||
}
|
||||
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
ORKFamilyHistoryResult *result = [super copyWithZone:zone];
|
||||
|
||||
result->_relatedPersons = ORKArrayCopyObjects(_relatedPersons);
|
||||
result->_displayedConditions = [_displayedConditions copy];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSUInteger)hash {
|
||||
return super.hash ^ self.relatedPersons.hash ^ self.displayedConditions.hash;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright (c) 2023, 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/ORKStep.h>
|
||||
|
||||
#import <ResearchKit/ORKTypes.h>
|
||||
|
||||
@class ORKConditionStepConfiguration;
|
||||
@class ORKRelativeGroup;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
A concrete subclass that will provide a participant with a
|
||||
family history survey.
|
||||
*/
|
||||
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKFamilyHistoryStep : ORKStep
|
||||
|
||||
@property (nonatomic, copy) ORKConditionStepConfiguration *conditionStepConfiguration;
|
||||
@property (nonatomic, copy) NSArray<ORKRelativeGroup *> *relativeGroups;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
Copyright (c) 2023, 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 "ORKFamilyHistoryStep.h"
|
||||
|
||||
#import "ORKAnswerFormat_Internal.h"
|
||||
#import "ORKCollectionResult.h"
|
||||
#import "ORKConditionStepConfiguration.h"
|
||||
#import "ORKFormStep.h"
|
||||
#import "ORKHelpers_Internal.h"
|
||||
#import "ORKRelativeGroup.h"
|
||||
|
||||
|
||||
@implementation ORKFamilyHistoryStep
|
||||
|
||||
- (instancetype)initWithIdentifier:(NSString *)identifier {
|
||||
self = [super initWithIdentifier:identifier];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)validateParameters {
|
||||
[super validateParameters];
|
||||
|
||||
// validate that atleast one condition has been provided
|
||||
if (self.conditionStepConfiguration.conditions.count == 0) {
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException
|
||||
reason:@"At least one ORKHealthCondition must be added to the ORKConditionStepConfiguration object"
|
||||
userInfo:nil];
|
||||
}
|
||||
|
||||
// validate that atleast one relative group has been provided
|
||||
if (self.relativeGroups.count == 0) {
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException
|
||||
reason:@"At least one ORKRelativeGroup must be provided"
|
||||
userInfo:nil];
|
||||
}
|
||||
|
||||
// validate that the identifiers for each relative group is unique
|
||||
NSMutableSet *identifiers = [NSMutableSet new];
|
||||
for (ORKRelativeGroup *relativeGroup in self.relativeGroups) {
|
||||
if ([identifiers containsObject:relativeGroup.identifier]) {
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException
|
||||
reason:@"Each ORKRelativeGroup must have a unique identifier"
|
||||
userInfo:nil];
|
||||
} else {
|
||||
[identifiers addObject:relativeGroup.identifier];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[super encodeWithCoder:aCoder];
|
||||
ORK_ENCODE_OBJ(aCoder, conditionStepConfiguration);
|
||||
ORK_ENCODE_OBJ(aCoder, relativeGroups);
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if (self) {
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, conditionStepConfiguration, ORKConditionStepConfiguration);
|
||||
ORK_DECODE_OBJ_ARRAY(aDecoder, relativeGroups, ORKRelativeGroup);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nonnull id)copyWithZone:(nullable NSZone *)zone {
|
||||
ORKFamilyHistoryStep *step = [super copyWithZone:zone];
|
||||
step->_conditionStepConfiguration = [_conditionStepConfiguration copy];
|
||||
step->_relativeGroups = [_relativeGroups copy];
|
||||
|
||||
return step;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
BOOL isParentSame = [super isEqual:object];
|
||||
|
||||
__typeof(self) castObject = object;
|
||||
return (isParentSame && ORKEqualObjects(_conditionStepConfiguration, castObject->_conditionStepConfiguration)
|
||||
&& ORKEqualObjects(_relativeGroups, castObject->_relativeGroups));
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -168,6 +176,7 @@ ORK_CLASS_AVAILABLE
|
||||
@param learnMoreItem The `ORKLearnMoreItem` to be presented when button is pressed.
|
||||
@param showsProgress A Boolean that determines if the formItem will display a progress indicator
|
||||
@param answerFormat The answer format for the form item.
|
||||
@param tagText The tag text to be presented in the card header view.
|
||||
@param optional A Boolean that determines whether the item is optional
|
||||
|
||||
@return An initialized form item.
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
self.optional = YES;
|
||||
self.useSurveyMode = YES;
|
||||
self.useCardView = YES;
|
||||
self.autoScrollEnabled = YES;
|
||||
self.cardViewStyle = ORKCardViewStyleDefault;
|
||||
}
|
||||
return self;
|
||||
@@ -64,6 +65,7 @@
|
||||
self.optional = YES;
|
||||
self.useSurveyMode = YES;
|
||||
self.useCardView = YES;
|
||||
self.autoScrollEnabled = YES;
|
||||
self.cardViewStyle = ORKCardViewStyleDefault;
|
||||
}
|
||||
return self;
|
||||
@@ -93,6 +95,7 @@
|
||||
ORKFormStep *step = [super copyWithZone:zone];
|
||||
step.formItems = ORKArrayCopyObjects(_formItems);
|
||||
step.cardViewStyle = self.cardViewStyle;
|
||||
step.autoScrollEnabled = self.autoScrollEnabled;
|
||||
return step;
|
||||
}
|
||||
|
||||
@@ -102,7 +105,8 @@
|
||||
__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 @@
|
||||
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 @@
|
||||
[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);
|
||||
}
|
||||
@@ -176,6 +182,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
- (NSSet<HKObjectType *> *)requestedHealthKitTypesForReading {
|
||||
NSMutableSet<HKObjectType *> *healthTypes = [NSMutableSet set];
|
||||
|
||||
@@ -189,6 +196,7 @@
|
||||
|
||||
return healthTypes.count ? healthTypes : nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -29,9 +29,12 @@
|
||||
*/
|
||||
|
||||
|
||||
#import <HealthKit/HealthKit.h>
|
||||
#import <ResearchKit/ORKAnswerFormat.h>
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
#import <HealthKit/HealthKit.h>
|
||||
#endif
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
@@ -70,6 +73,8 @@ ORK_EXTERN ORKBloodTypeIdentifier const ORKBloodTypeIdentifierONegative;
|
||||
|
||||
You can use the HealthKit characteristic answer format to let users autofill information, such as their blood type or date of birth.
|
||||
*/
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKHealthKitCharacteristicTypeAnswerFormat : ORKAnswerFormat
|
||||
|
||||
@@ -221,6 +226,6 @@ included in the question result generated by form items or question steps
|
||||
- (NSString *)localizedUnitString;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#import "ORKQuestionResult_Private.h"
|
||||
#import "ORKResult.h"
|
||||
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
#pragma mark - ORKHealthAnswerFormat
|
||||
|
||||
ORKBiologicalSexIdentifier const ORKBiologicalSexIdentifierFemale = @"HKBiologicalSexFemale";
|
||||
@@ -420,3 +420,4 @@ NSString *ORKHKBloodTypeString(HKBloodType bloodType) {
|
||||
}
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Copyright (c) 2023, Apple Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <ResearchKit/ORKTypes.h>
|
||||
|
||||
@class ORKTaskResult;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
A base class that represents a single health condition displayed
|
||||
by the family history step.
|
||||
*/
|
||||
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKHealthCondition : NSObject <NSSecureCoding, NSCopying>
|
||||
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Creates a new health condition with the specified identifier.
|
||||
|
||||
This method is the primary designated initializer.
|
||||
|
||||
@param identifier The unique identifier of the health condition.
|
||||
@param name The name displayed to the participant for selection.
|
||||
@param value The value stored to the result if the health condition is selected.
|
||||
*/
|
||||
|
||||
- (instancetype)initWithIdentifier:(NSString *)identifier
|
||||
displayName:(NSString *)name
|
||||
value:(NSObject<NSCopying, NSSecureCoding> *)value NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@property (nonatomic, readonly, copy) NSString *identifier;
|
||||
@property (nonatomic, readonly, copy) NSString *displayName;
|
||||
@property (nonatomic, readonly, copy) NSObject<NSCopying, NSSecureCoding> *value;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
Copyright (c) 2023, 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 "ORKHealthCondition.h"
|
||||
|
||||
#import "ORKAnswerFormat_Internal.h"
|
||||
#import "ORKCollectionResult.h"
|
||||
#import "ORKHelpers_Internal.h"
|
||||
|
||||
|
||||
@implementation ORKHealthCondition
|
||||
|
||||
- (instancetype)initWithIdentifier:(NSString *)identifier
|
||||
displayName:(NSString *)name
|
||||
value:(NSObject<NSCopying,NSSecureCoding> *)value {
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
_identifier = [identifier copy];
|
||||
_displayName = [name copy];
|
||||
_value = [value copy];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
ORK_ENCODE_OBJ(aCoder, identifier);
|
||||
ORK_ENCODE_OBJ(aCoder, displayName);
|
||||
ORK_ENCODE_OBJ(aCoder, value);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, identifier, NSString);
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, displayName, NSString);
|
||||
ORK_DECODE_OBJ_CLASSES(aDecoder, value, ORKAllowableValueClasses());
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nonnull id)copyWithZone:(nullable NSZone *)zone {
|
||||
ORKHealthCondition *healthCondition = [[[self class] allocWithZone:zone] initWithIdentifier:[_identifier copy]
|
||||
displayName:[_displayName copy]
|
||||
value:[_value copy]];
|
||||
return healthCondition;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
if ([self class] != [object class]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
__typeof(self) castObject = object;
|
||||
return (ORKEqualObjects(self.identifier, castObject.identifier)
|
||||
&& ORKEqualObjects(self.displayName, castObject.displayName)
|
||||
&& ORKEqualObjects(self.value, castObject.value));
|
||||
}
|
||||
|
||||
- (NSUInteger)hash {
|
||||
return super.hash ^ self.identifier.hash ^ self.displayName.hash ^ self.value.hash;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -30,7 +30,10 @@
|
||||
|
||||
#import "ORKHealthKitPermissionType.h"
|
||||
#import "ORKHelpers_Internal.h"
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
#import <HealthKit/HealthKit.h>
|
||||
#endif
|
||||
|
||||
static NSString *const Symbol = @"heart.fill";
|
||||
static uint32_t const IconTintColor = 0xFF5E5E;
|
||||
@@ -80,6 +83,7 @@ static uint32_t const IconTintColor = 0xFF5E5E;
|
||||
}
|
||||
|
||||
- (void)checkHealthKitAuthorizationStatus {
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
if (![HKHealthStore isHealthDataAvailable]) {
|
||||
_permissionState = ORKRequestPermissionsStateNotSupported;
|
||||
if (self.permissionsStatusUpdateCallback != nil) {
|
||||
@@ -108,6 +112,8 @@ static uint32_t const IconTintColor = 0xFF5E5E;
|
||||
|
||||
});
|
||||
}];
|
||||
#endif // ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
|
||||
}
|
||||
|
||||
- (BOOL)canContinue {
|
||||
@@ -118,6 +124,7 @@ static uint32_t const IconTintColor = 0xFF5E5E;
|
||||
}
|
||||
|
||||
- (void)requestPermission {
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
[[HKHealthStore new] requestAuthorizationToShareTypes:_sampleTypesToWrite readTypes:_objectTypesToRead completion:^(BOOL success, NSError * _Nullable error) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (error) {
|
||||
@@ -130,6 +137,7 @@ static uint32_t const IconTintColor = 0xFF5E5E;
|
||||
}
|
||||
});
|
||||
}];
|
||||
#endif // ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
|
||||
@@ -31,8 +31,9 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "ORKOperation.h"
|
||||
#import "ORKDefines.h"
|
||||
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
@class ORKDataCollectionManager;
|
||||
@class ORKCollector;
|
||||
@protocol ORKHealthCollectable;
|
||||
@@ -47,3 +48,4 @@
|
||||
- (instancetype)initWithCollector:(ORKCollector<ORKHealthCollectable> *)collector mananger:(ORKDataCollectionManager *)manager;
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#import "ORKCollector_Internal.h"
|
||||
#import "ORKDataCollectionManager_Internal.h"
|
||||
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
static NSUInteger const QueryLimitSize = 1000;
|
||||
|
||||
@implementation ORKHealthSampleQueryOperation {
|
||||
@@ -245,3 +245,4 @@ static NSUInteger const QueryLimitSize = 1000;
|
||||
}
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
||||
@@ -559,3 +559,4 @@ NSNumberFormatter *ORKDecimalNumberFormatter(void) {
|
||||
numberFormatter.usesGroupingSeparator = NO;
|
||||
return numberFormatter;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
|
||||
@import UIKit;
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#import <ResearchKit/ORKTypes.h>
|
||||
@@ -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]);
|
||||
@@ -371,6 +372,13 @@ ORK_INLINE double ORKPoundsToKilograms(double pounds) {
|
||||
return ORKPoundsAndOuncesToKilograms(pounds, 0);
|
||||
}
|
||||
|
||||
ORK_INLINE double ORKForceDoubleToLimits(double value) {
|
||||
if (value == NAN || value == INFINITY) {
|
||||
return DBL_MAX;
|
||||
}
|
||||
return fmin(fmax(value, -DBL_MAX), DBL_MAX);
|
||||
}
|
||||
|
||||
ORK_INLINE UIColor *ORKOpaqueColorWithReducedAlphaFromBaseColor(UIColor *baseColor, NSUInteger colorIndex, NSUInteger totalColors) {
|
||||
UIColor *color = baseColor;
|
||||
if (totalColors > 1) {
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
*/
|
||||
|
||||
|
||||
@import Foundation;
|
||||
#import <Foundation/Foundation.h>
|
||||
#if TARGET_OS_IOS
|
||||
#import <ResearchKit/ORKDefines.h>
|
||||
#endif
|
||||
|
||||
@@ -37,9 +37,11 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
A permission type object that requests access for location data.
|
||||
*/
|
||||
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKLocationPermissionType : ORKPermissionType
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#import "ORKLocationPermissionType.h"
|
||||
#import "ORKHelpers_Internal.h"
|
||||
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
#import <CoreLocation/CLLocationManagerDelegate.h>
|
||||
#import <ResearchKit/CLLocationManager+ResearchKit.h>
|
||||
|
||||
@@ -116,3 +117,4 @@ static const uint32_t IconDarkTintColor = 0x00A36C;
|
||||
}
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
||||
@@ -43,20 +43,25 @@ static const uint32_t IconDarkTintColor = 0xEF6FD8;
|
||||
@property (nonatomic, readonly, assign) BOOL canContinue;
|
||||
@end
|
||||
|
||||
@implementation ORKMotionActivityPermissionType
|
||||
@implementation ORKMotionActivityPermissionType {
|
||||
__weak NSTimer *_checkStatusTimer;
|
||||
}
|
||||
|
||||
+ (instancetype)new {
|
||||
return [[ORKMotionActivityPermissionType alloc] init];
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)cleanUp {
|
||||
[self _invalidateCheckStatusTimer];
|
||||
}
|
||||
|
||||
- (CMMotionActivityManager *)activityManager {
|
||||
if (!_activityManager) {
|
||||
_activityManager = [[CMMotionActivityManager alloc] init];
|
||||
@@ -105,9 +110,33 @@ static const uint32_t IconDarkTintColor = 0xEF6FD8;
|
||||
[self.activityManager startActivityUpdatesToQueue:[NSOperationQueue mainQueue]
|
||||
withHandler:^(CMMotionActivity * _Nullable activity) {}];
|
||||
[self.activityManager stopActivityUpdates];
|
||||
|
||||
if (self.permissionsStatusUpdateCallback != nil) {
|
||||
self.permissionsStatusUpdateCallback();
|
||||
}
|
||||
|
||||
if (!_checkStatusTimer) {
|
||||
__weak typeof(self) weakSelf = self;
|
||||
_checkStatusTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
|
||||
target:weakSelf
|
||||
selector:@selector(_checkPermissionStatus)
|
||||
userInfo:nil
|
||||
repeats:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_checkPermissionStatus {
|
||||
if ([self permissionState] == ORKRequestPermissionsStateConnected && self.permissionsStatusUpdateCallback != nil) {
|
||||
self.permissionsStatusUpdateCallback();
|
||||
[self _invalidateCheckStatusTimer];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_invalidateCheckStatusTimer {
|
||||
if (_checkStatusTimer) {
|
||||
[_checkStatusTimer invalidate];
|
||||
_checkStatusTimer = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
|
||||
@@ -73,12 +73,14 @@
|
||||
return ORKPermissionNone;
|
||||
}
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
- (NSSet<HKObjectType *> *)requestedHealthKitTypesForReading {
|
||||
if ([self.pageTask respondsToSelector:@selector(requestedHealthKitTypesForReading)]) {
|
||||
return [self.pageTask requestedHealthKitTypesForReading];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ ORK_CLASS_AVAILABLE
|
||||
@property (nonatomic, assign, readonly) BOOL canContinue;
|
||||
|
||||
- (void)requestPermission;
|
||||
- (void)cleanUp;
|
||||
|
||||
+ (ORKHealthKitPermissionType *)healthKitPermissionTypeWithSampleTypesToWrite:(nullable NSSet<HKSampleType *> *)sampleTypesToWrite
|
||||
objectTypesToRead:(nullable NSSet<HKObjectType *> *)objectTypesToRead;
|
||||
@@ -79,7 +80,9 @@ ORK_CLASS_AVAILABLE
|
||||
|
||||
+ (ORKMotionActivityPermissionType *) deviceMotionPermissionType;
|
||||
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
+ (ORKLocationPermissionType *) locationPermissionType;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -66,6 +66,10 @@
|
||||
ORKThrowMethodUnavailableException();
|
||||
}
|
||||
|
||||
- (void)cleanUp {
|
||||
// left empty for optional subclass override
|
||||
}
|
||||
|
||||
+ (ORKHealthKitPermissionType *)healthKitPermissionTypeWithSampleTypesToWrite:(NSSet<HKSampleType *> *)sampleTypesToWrite objectTypesToRead:(NSSet<HKObjectType *> *)objectTypesToRead {
|
||||
return [[ORKHealthKitPermissionType alloc] initWithSampleTypesToWrite:sampleTypesToWrite
|
||||
objectTypesToRead:objectTypesToRead];
|
||||
@@ -83,9 +87,11 @@
|
||||
return [[ORKMotionActivityPermissionType alloc] init];
|
||||
}
|
||||
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
+ (ORKLocationPermissionType *) locationPermissionType {
|
||||
return [[ORKLocationPermissionType alloc] init];
|
||||
}
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -33,7 +33,10 @@
|
||||
#endif
|
||||
|
||||
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
#import <CoreLocation/CLLocation.h>
|
||||
#endif
|
||||
|
||||
#import <Contacts/Contacts.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@@ -150,8 +153,9 @@ ORK_CLASS_AVAILABLE
|
||||
@end
|
||||
|
||||
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
/**
|
||||
The `ORKLocation` class represents the location addess obtained from a locaton question.
|
||||
The `ORKLocation` class represents the location addess obtained from a location question.
|
||||
*/
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKLocation : NSObject <NSCopying, NSSecureCoding>
|
||||
@@ -180,7 +184,7 @@ ORK_CLASS_AVAILABLE
|
||||
@property (nonatomic, copy, readonly, nullable) CNPostalAddress *postalAddress;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
A result object from a location answer format.
|
||||
@@ -192,6 +196,7 @@ ORK_CLASS_AVAILABLE
|
||||
completes, it may be appropriate to serialize it for transmission to a server,
|
||||
or to immediately perform analysis on it.
|
||||
*/
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKLocationQuestionResult : ORKQuestionResult
|
||||
|
||||
@@ -201,7 +206,7 @@ ORK_CLASS_AVAILABLE
|
||||
@property (nonatomic, copy, nullable) ORKLocation *locationAnswer;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
A result object from a multiple-component picker-style choice-based answer format.
|
||||
|
||||
@@ -326,7 +326,7 @@
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
#pragma mark - ORKLocationQuestionResult
|
||||
|
||||
@implementation ORKLocation
|
||||
@@ -469,6 +469,7 @@ static NSString *const RegionIdentifierKey = @"region.identifier";
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
#pragma mark - ORKSESQuestionResult
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#import <ResearchKit/ORKQuestionResult.h>
|
||||
#endif
|
||||
|
||||
@import MapKit;
|
||||
#import <MapKit/MapKit.h>
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@@ -49,7 +49,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
@interface ORKLocation ()
|
||||
|
||||
- (instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate
|
||||
@@ -60,5 +60,5 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
- (instancetype)initWithPlacemark:(CLPlacemark *)placemark userInput:(NSString *)userInput;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -31,10 +31,12 @@
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <HealthKit/HealthKit.h>
|
||||
#import <ResearchKit/ORKDefines.h>
|
||||
#import <Availability.h>
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
#import <HealthKit/HealthKit.h>
|
||||
#endif
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@@ -105,8 +107,9 @@ ORK_CLASS_AVAILABLE
|
||||
If your recorder requires or would benefit from read access to HealthKit at
|
||||
runtime during the task, return the appropriate set of `HKSampleType` objects.
|
||||
*/
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
- (nullable NSSet<HKObjectType *> *)requestedHealthKitTypesForReading;
|
||||
|
||||
#endif
|
||||
@end
|
||||
|
||||
|
||||
@@ -309,6 +312,8 @@ ORK_CLASS_AVAILABLE
|
||||
|
||||
No additional parameters besides the identifier are required.
|
||||
*/
|
||||
|
||||
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKLocationRecorderConfiguration : ORKRecorderConfiguration
|
||||
|
||||
@@ -333,99 +338,7 @@ ORK_CLASS_AVAILABLE
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@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
|
||||
#endif
|
||||
|
||||
/**
|
||||
A configuration object that records streaming audio data during an active step.
|
||||
|
||||
@@ -89,9 +89,12 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
- (NSSet<HKObjectType *> *)requestedHealthKitTypesForReading {
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (ORKPermissionMask)requestedPermissionMask {
|
||||
return ORKPermissionNone;
|
||||
}
|
||||
|
||||
@@ -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 ()
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright (c) 2023, Apple Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <ResearchKit/ORKAnswerFormat.h>
|
||||
#import <ResearchKit/ORKFormStep.h>
|
||||
#import <ResearchKit/ORKTypes.h>
|
||||
|
||||
|
||||
@class ORKTaskResult;
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
An object that represents a relative added during
|
||||
a family health history survey.
|
||||
*/
|
||||
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKRelatedPerson : NSObject <NSSecureCoding, NSCopying>
|
||||
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Creates a new related person with the specified identifier.
|
||||
|
||||
This method is the primary designated initializer.
|
||||
|
||||
@param identifier The unique identifier of the related person.
|
||||
@param groupIdentifier The identifier of the relative group to which the person belongs.
|
||||
@param identifierForCellTitle The identifier of the result value to be used for the relative's cell title.
|
||||
@param result The task result generated for the relative's health history survey.
|
||||
*/
|
||||
|
||||
- (instancetype)initWithIdentifier:(NSString *)identifier
|
||||
groupIdentifier:(NSString *)groupIdentifier
|
||||
identifierForCellTitle:(NSString *)identifierForCellTitle
|
||||
taskResult:(ORKTaskResult *)result NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@property (nonatomic, readonly, copy) NSString *identifier;
|
||||
@property (nonatomic, readonly, copy) NSString *groupIdentifier;
|
||||
@property (nonatomic, readonly, copy) NSString *identifierForCellTitle;
|
||||
@property (nonatomic, copy) ORKTaskResult *taskResult;
|
||||
|
||||
- (nullable NSString *)getTitleValueWithIdentifier:(NSString *)identifier;
|
||||
|
||||
- (NSArray<NSString *> *)getDetailListValuesWithIdentifiers:(NSArray<NSString *> *)identifiers
|
||||
displayInfoKeyAndValues:(NSDictionary<NSString *, NSDictionary<NSString *, NSString *> *> *)displayInfoKeyAndValues;
|
||||
|
||||
- (NSArray<NSString *> *)getConditionsListWithStepIdentifier:(NSString *)stepIdentifier
|
||||
formItemIdentifier:(NSString *)formItemIdentifier
|
||||
conditionsKeyValues:(NSDictionary<NSString *, NSString *> *)conditionsKeyValues;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
Copyright (c) 2023, 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 "ORKRelatedPerson.h"
|
||||
|
||||
#import <ResearchKit/ORKAnswerFormat_Internal.h>
|
||||
#import <ResearchKit/ORKCollectionResult.h>
|
||||
#import <ResearchKit/ORKCollectionResult_Private.h>
|
||||
#import <ResearchKit/ORKResult_Private.h>
|
||||
#import <ResearchKit/ORKStep_Private.h>
|
||||
#import <ResearchKit/ORKQuestionResult.h>
|
||||
#import <ResearchKit/ORKQuestionResult_Private.h>
|
||||
#import <ResearchKit/ORKHelpers_Internal.h>
|
||||
|
||||
|
||||
|
||||
@implementation ORKRelatedPerson {
|
||||
}
|
||||
|
||||
- (instancetype)initWithIdentifier:(NSString *)identifier
|
||||
groupIdentifier:(NSString *)groupIdentifier
|
||||
identifierForCellTitle:(NSString *)identifierForCellTitle
|
||||
taskResult:(ORKTaskResult *)result {
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
_identifier = [identifier copy];
|
||||
_groupIdentifier = [groupIdentifier copy];
|
||||
_identifierForCellTitle = [identifierForCellTitle copy];
|
||||
_taskResult = [result copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
ORK_ENCODE_OBJ(aCoder, identifier);
|
||||
ORK_ENCODE_OBJ(aCoder, groupIdentifier);
|
||||
ORK_ENCODE_OBJ(aCoder, identifierForCellTitle);
|
||||
ORK_ENCODE_OBJ(aCoder, taskResult);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, identifier, NSString);
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, groupIdentifier, NSString);
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, identifierForCellTitle, NSString);
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, taskResult, ORKTaskResult);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)copyWithZone:(nullable NSZone *)zone {
|
||||
ORKRelatedPerson *relatedPerson = [[[self class] allocWithZone:zone] initWithIdentifier:[_identifier copy]
|
||||
groupIdentifier:[_groupIdentifier copy]
|
||||
identifierForCellTitle: [_identifierForCellTitle copy]
|
||||
taskResult:[_taskResult copy]];
|
||||
return relatedPerson;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
if ([self class] != [object class]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
__typeof(self) castObject = object;
|
||||
return (ORKEqualObjects(self.identifier, castObject.identifier)
|
||||
&& ORKEqualObjects(self.groupIdentifier, castObject.groupIdentifier)
|
||||
&& ORKEqualObjects(self.identifierForCellTitle, castObject.identifierForCellTitle)
|
||||
&& ORKEqualObjects(self.taskResult, castObject.taskResult));
|
||||
}
|
||||
|
||||
- (nullable NSString *)getTitleValueWithIdentifier:(NSString *)identifier {
|
||||
return [self getResultValueWithIdentifier:identifier];
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)getDetailListValuesWithIdentifiers:(NSArray<NSString *> *)identifiers
|
||||
displayInfoKeyAndValues:(nonnull NSDictionary<NSString *,NSDictionary<NSString *,NSString *> *> *)displayInfoKeyAndValues {
|
||||
NSMutableArray<NSString *> *detailListValues = [NSMutableArray new];
|
||||
|
||||
for (NSString *identifier in identifiers) {
|
||||
NSString *result = [self getResultValueWithIdentifier:identifier];
|
||||
|
||||
if ([result isKindOfClass:[ORKDontKnowAnswer class]]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NSString *value = ![result isKindOfClass:[NSString class]] ? [NSString stringWithFormat:@"%i", result.intValue] : result;
|
||||
if (value && ![value isEqual:@"0"]) {
|
||||
NSString *displayText = displayInfoKeyAndValues[identifier][value];
|
||||
if (![self shouldSkipListValue:displayText] && ![self shouldSkipListValue:value]) {
|
||||
[detailListValues addObject: displayText != nil ? displayText : value];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [detailListValues copy];
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)getConditionsListWithStepIdentifier:(NSString *)stepIdentifier
|
||||
formItemIdentifier:(NSString *)formItemIdentifier
|
||||
conditionsKeyValues:(nonnull NSDictionary<NSString *,NSString *> *)conditionsKeyValues {
|
||||
ORKStepResult *stepResult = (ORKStepResult *)[self.taskResult resultForIdentifier:stepIdentifier];
|
||||
|
||||
ORKChoiceQuestionResult *choiceQuestionResult = (ORKChoiceQuestionResult *)[stepResult resultForIdentifier:formItemIdentifier];
|
||||
NSArray<NSString *> *conditionsList = (NSArray<NSString *> *)choiceQuestionResult.choiceAnswers;
|
||||
|
||||
NSMutableArray<NSString *> *conditionListDisplayValues = [NSMutableArray new];
|
||||
|
||||
BOOL didSkipValue = NO;
|
||||
for (NSString *condition in conditionsList) {
|
||||
NSString *value = [conditionsKeyValues valueForKey:condition];
|
||||
|
||||
if ([self shouldSkipListValue:value]) {
|
||||
didSkipValue = YES;
|
||||
} else {
|
||||
NSString *displayString = [[value lowercaseString] isEqual:@"none of the above"] ? ORKLocalizedString(@"FAMILY_HISTORY_NONE_SELECTED", @"") : value;
|
||||
[conditionListDisplayValues addObject:displayString];
|
||||
}
|
||||
}
|
||||
|
||||
if (didSkipValue && conditionListDisplayValues.count == 0) {
|
||||
[conditionListDisplayValues addObject:@""];
|
||||
}
|
||||
|
||||
return [conditionListDisplayValues copy];
|
||||
}
|
||||
|
||||
- (nullable NSString *)getResultValueWithIdentifier:(NSString *)identifier {
|
||||
|
||||
for (ORKStepResult *result in _taskResult.results) {
|
||||
ORKQuestionResult *questionResult = (ORKQuestionResult *)[result resultForIdentifier:identifier];
|
||||
|
||||
if (questionResult) {
|
||||
if ([questionResult isKindOfClass:[ORKChoiceQuestionResult class]]) {
|
||||
ORKChoiceQuestionResult *choiceQuestionResult = (ORKChoiceQuestionResult *)questionResult;
|
||||
return (NSString *)choiceQuestionResult.choiceAnswers.firstObject;
|
||||
} else {
|
||||
NSString *answer = (NSString *)questionResult.answer;
|
||||
|
||||
|
||||
return answer;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)shouldSkipListValue:(NSString *)value {
|
||||
return ([[value lowercaseString] isEqual:@"i don't know"] || [[value lowercaseString] isEqual:@"i don’t know"] || [[value lowercaseString] isEqual:@"i prefer not to answer"]);
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright (c) 2023, Apple Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <ResearchKit/ORKTypes.h>
|
||||
|
||||
|
||||
@class ORKTaskResult;
|
||||
@class ORKFormStep;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
An object to represent a relative type displayed
|
||||
during a family health history survey.
|
||||
|
||||
Example relative groups could be parents, children, or siblings.
|
||||
*/
|
||||
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKRelativeGroup : NSObject
|
||||
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Creates a new relative group with the specified identifier.
|
||||
|
||||
This method is the primary designated initializer.
|
||||
|
||||
@param identifier The unique identifier of the relative group.
|
||||
@param name The name of the relative group. This should be the singular representation.
|
||||
@param title The table section title for the relative group.
|
||||
@param detailText The detail text displayed in the table section header for the relative group.
|
||||
@param identifierForCellTitle The identifier of the result value to be used for the relative's cell title.
|
||||
@param maxAllowed The maximum amount of relatives that are allowed to be added by the participant.
|
||||
@param formSteps The form steps that will precede the health conditions step during the survey.
|
||||
@param detailTextIdentifiers The identifiers of each result value that will be displayed in the relative's card view.
|
||||
*/
|
||||
|
||||
- (instancetype)initWithIdentifier:(NSString *)identifier
|
||||
name:(NSString *)name
|
||||
sectionTitle:(NSString *)title
|
||||
sectionDetailText:(NSString *)detailText
|
||||
identifierForCellTitle:(NSString *)identifierForCellTitle
|
||||
maxAllowed:(NSUInteger)maxAllowed
|
||||
formSteps:(NSArray<ORKFormStep *> *)formSteps
|
||||
detailTextIdentifiers:(NSArray<NSString *> *)detailTextIdentifiers NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@property (nonatomic, readonly, copy) NSString *identifier;
|
||||
@property (nonatomic, readonly, copy) NSString *name;
|
||||
@property (nonatomic, readonly, copy) NSString *sectionTitle;
|
||||
@property (nonatomic, readonly, copy) NSString *sectionDetailText;
|
||||
@property (nonatomic, readonly, copy) NSString *identifierForCellTitle;
|
||||
@property (nonatomic, readonly) NSUInteger maxAllowed;
|
||||
@property (nonatomic, readonly, copy) NSArray<ORKFormStep *> *formSteps;
|
||||
@property (nonatomic, readonly, copy) NSArray<NSString *> *detailTextIdentifiers;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Copyright (c) 2023, 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 "ORKRelativeGroup.h"
|
||||
|
||||
#import "ORKAnswerFormat_Private.h"
|
||||
#import "ORKCollectionResult.h"
|
||||
#import "ORKFormStep.h"
|
||||
#import "ORKHelpers_Internal.h"
|
||||
|
||||
|
||||
@implementation ORKRelativeGroup
|
||||
|
||||
- (instancetype)initWithIdentifier:(NSString *)identifier
|
||||
name:(NSString *)name
|
||||
sectionTitle:(NSString *)title
|
||||
sectionDetailText:(NSString *)detailText
|
||||
identifierForCellTitle:(NSString *)identifierForCellTitle
|
||||
maxAllowed:(NSUInteger)maxAllowed
|
||||
formSteps:(NSArray<ORKFormStep *> *)formSteps
|
||||
detailTextIdentifiers:(NSArray<NSString *> *)detailTextIdentifiers {
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
_identifier = identifier;
|
||||
_name = name;
|
||||
_sectionTitle = title;
|
||||
_sectionDetailText = detailText;
|
||||
_identifierForCellTitle = identifierForCellTitle;
|
||||
_maxAllowed = maxAllowed;
|
||||
_formSteps = formSteps;
|
||||
_detailTextIdentifiers = detailTextIdentifiers;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
ORK_ENCODE_OBJ(aCoder, identifier);
|
||||
ORK_ENCODE_OBJ(aCoder, name);
|
||||
ORK_ENCODE_OBJ(aCoder, sectionTitle);
|
||||
ORK_ENCODE_OBJ(aCoder, sectionDetailText);
|
||||
ORK_ENCODE_OBJ(aCoder, identifierForCellTitle);
|
||||
ORK_ENCODE_INTEGER(aCoder, maxAllowed);
|
||||
ORK_ENCODE_OBJ(aCoder, formSteps);
|
||||
ORK_ENCODE_OBJ(aCoder, detailTextIdentifiers);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, identifier, NSString);
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, name, NSString);
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, sectionTitle, NSString);
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, sectionDetailText, NSString);
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, identifierForCellTitle, NSString);
|
||||
ORK_DECODE_INTEGER(aDecoder, maxAllowed);
|
||||
ORK_DECODE_OBJ_ARRAY(aDecoder, formSteps, ORKFormStep);
|
||||
ORK_DECODE_OBJ_ARRAY(aDecoder, detailTextIdentifiers, NSString);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nonnull id)copyWithZone:(nullable NSZone *)zone {
|
||||
ORKRelativeGroup *relativeGroup = [[[self class] allocWithZone:zone] initWithIdentifier:[_identifier copy]
|
||||
name:[_name copy]
|
||||
sectionTitle:[_sectionTitle copy]
|
||||
sectionDetailText:[_sectionDetailText copy]
|
||||
identifierForCellTitle:[_identifierForCellTitle copy]
|
||||
maxAllowed:_maxAllowed
|
||||
formSteps:[_formSteps copy]
|
||||
detailTextIdentifiers:[_detailTextIdentifiers copy]];
|
||||
return relativeGroup;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
if ([self class] != [object class]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
__typeof(self) castObject = object;
|
||||
return (ORKEqualObjects(self.identifier, castObject.identifier)
|
||||
&& ORKEqualObjects(self.name, castObject.name)
|
||||
&& ORKEqualObjects(self.sectionTitle, castObject.sectionTitle)
|
||||
&& ORKEqualObjects(self.sectionDetailText, castObject.sectionDetailText)
|
||||
&& ORKEqualObjects(self.identifierForCellTitle, castObject.identifierForCellTitle)
|
||||
&& ORKEqualObjects(self.formSteps, castObject.formSteps)
|
||||
&& ORKEqualObjects(self.detailTextIdentifiers, castObject.detailTextIdentifiers)
|
||||
&& self.maxAllowed == castObject.maxAllowed);
|
||||
}
|
||||
|
||||
- (NSUInteger)hash {
|
||||
return super.hash ^ _identifier.hash ^ _name.hash ^ _sectionTitle.hash ^ _sectionDetailText.hash ^ _identifierForCellTitle.hash ^ _formSteps.hash ^ _detailTextIdentifiers.hash;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -540,6 +540,7 @@ within the specified `NSTimeInterval` values.
|
||||
refer to the contained `ORKConsentSignatureResult`
|
||||
corresponding to the signature collected by the consent
|
||||
review step.
|
||||
@param didConsent Boolean to indicate if the user consented.
|
||||
@return A result predicate.
|
||||
*/
|
||||
+ (NSPredicate *)predicateForConsentWithResultSelector:(ORKResultSelector *)resultSelector
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
@import UIKit;
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#import <ResearchKit/ORKSkin.h>
|
||||
|
||||
@@ -51,19 +51,19 @@ ORK_EXTERN NSString *const ORKNullStepIdentifier ORK_AVAILABLE_DECL;
|
||||
The base object for composing a task.
|
||||
|
||||
``ORKStep`` is the base class for the steps that can compose a task for presentation
|
||||
in an ``ORKTaskViewController`` object. Each ``ORKStep`` object represents one logical piece of data
|
||||
in an ORKTaskViewController object. Each ``ORKStep`` object represents one logical piece of data
|
||||
entry or activity in a larger task.
|
||||
|
||||
A step can be a question, an active test, or a simple instruction. Pair an ``ORKStep``
|
||||
subclass with an ``ORKStepViewController`` subclass to display the step.
|
||||
subclass with an ORKStepViewController subclass to display the step.
|
||||
|
||||
To use a step, instantiate an ``ORKStep`` object and populate its properties. Add the step to a task,
|
||||
such as an ``ORKOrderedTask`` object, then present the task using ``ORKTaskViewController``.
|
||||
such as an ``ORKOrderedTask`` object, then present the task using ORKTaskViewController.
|
||||
|
||||
To implement a new type of step, subclass ``ORKStep`` and add your additional
|
||||
properties.Then subclass ``ORKStepViewController`` and implement
|
||||
properties.Then subclass ORKStepViewController and implement
|
||||
your user interface. If your step is timed, or requires sensor data collection,
|
||||
subclass ``ORKActiveStep`` and ``ORKActiveStepViewController``.
|
||||
subclass ``ORKActiveStep`` and ORKActiveStepViewController.
|
||||
*/
|
||||
|
||||
ORK_CLASS_AVAILABLE API_AVAILABLE(ios(11.0), watchos(6.0))
|
||||
@@ -180,14 +180,14 @@ ORK_CLASS_AVAILABLE API_AVAILABLE(ios(11.0), watchos(6.0))
|
||||
/**
|
||||
A property that gates automatic tint color image changes based on appearance changes.
|
||||
|
||||
The default value for this property is ``NO``.
|
||||
The default value for this property is NO.
|
||||
*/
|
||||
@property (nonatomic) BOOL shouldAutomaticallyAdjustImageTintColor;
|
||||
|
||||
/**
|
||||
A property that determines whether to show progress for this step when presented.
|
||||
|
||||
The default is ``YES``.
|
||||
The default is YES.
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL showsProgress;
|
||||
|
||||
@@ -240,7 +240,7 @@ ORK_CLASS_AVAILABLE API_AVAILABLE(ios(11.0), watchos(6.0))
|
||||
Checks the parameters of the step and throws exceptions on invalid parameters.
|
||||
|
||||
This method is called when there is a need to validate the step's parameters, which is typically
|
||||
the case when adding a step to an ``ORKStepViewController`` object, and when presenting the
|
||||
the case when adding a step to an ORKStepViewController object, and when presenting the
|
||||
step view controller.
|
||||
|
||||
Subclasses should override this method to provide validation of their additional
|
||||
@@ -272,7 +272,7 @@ API_AVAILABLE(ios(11))
|
||||
/**
|
||||
A Boolean value indicating if the body items of the step should build in.
|
||||
|
||||
Default value is ``NO`` resulting in all body items being displayed. Set to ``YES`` to
|
||||
Default value is NO resulting in all body items being displayed. Set to YES to
|
||||
only show the first item and subsequent items will build in on continue.
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL buildInBodyItems API_AVAILABLE(ios(11)) API_UNAVAILABLE(watchos);
|
||||
@@ -303,7 +303,7 @@ API_AVAILABLE(ios(11))
|
||||
/**
|
||||
A view controller that positions an image inside an image view that the step uses.
|
||||
|
||||
Depending on the subclass of the step, ``ORKStepView`` uses a specific ``UIImageView``, and
|
||||
Depending on the subclass of the step, ORKStepView uses a specific UIImageView, and
|
||||
``imageContentMode`` sets the content mode of used image view.
|
||||
*/
|
||||
|
||||
|
||||
@@ -182,6 +182,11 @@ ORK_CLASS_AVAILABLE
|
||||
*/
|
||||
@property (nonatomic) BOOL pinNavigationContainer;
|
||||
|
||||
/**
|
||||
A property that manually overrides the bottomPadding of the content view
|
||||
*/
|
||||
@property (nonatomic, copy, nullable) NSNumber *bottomPadding;
|
||||
|
||||
/**
|
||||
Returns the number of sections in the tableview used to display this step. Default = `1`.
|
||||
|
||||
|
||||
@@ -169,6 +169,8 @@ ORKDefineStringKey(ORKBasicCellReuseIdentifier);
|
||||
step->_bulletType = _bulletType;
|
||||
step->_bulletIconNames = ORKArrayCopyObjects(_bulletIconNames);
|
||||
step->_allowsSelection = _allowsSelection;
|
||||
step->_bottomPadding = _bottomPadding;
|
||||
|
||||
return step;
|
||||
}
|
||||
|
||||
@@ -186,6 +188,7 @@ ORKDefineStringKey(ORKBasicCellReuseIdentifier);
|
||||
ORK_DECODE_OBJ_ARRAY(aDecoder, bulletIconNames, NSString);
|
||||
ORK_DECODE_BOOL(aDecoder, allowsSelection);
|
||||
ORK_DECODE_BOOL(aDecoder, pinNavigationContainer);
|
||||
ORK_DECODE_OBJ_CLASS(aDecoder, bottomPadding, NSNumber);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -197,6 +200,7 @@ ORKDefineStringKey(ORKBasicCellReuseIdentifier);
|
||||
ORK_ENCODE_OBJ(aCoder, bulletIconNames);
|
||||
ORK_ENCODE_BOOL(aCoder, allowsSelection);
|
||||
ORK_ENCODE_BOOL(aCoder, pinNavigationContainer);
|
||||
ORK_ENCODE_OBJ(aCoder, bottomPadding);
|
||||
}
|
||||
|
||||
#pragma mark - Equality
|
||||
@@ -210,11 +214,12 @@ ORKDefineStringKey(ORKBasicCellReuseIdentifier);
|
||||
&& (self.bulletType == castObject.bulletType)
|
||||
&& (self.allowsSelection == castObject.allowsSelection)
|
||||
&& ORKEqualObjects(self.bulletIconNames, castObject.bulletIconNames)
|
||||
&& self.pinNavigationContainer == castObject.pinNavigationContainer);
|
||||
&& self.pinNavigationContainer == castObject.pinNavigationContainer)
|
||||
&& ORKEqualObjects(self.bottomPadding, castObject.bottomPadding);
|
||||
}
|
||||
|
||||
- (NSUInteger)hash {
|
||||
return super.hash ^ self.items.hash ^ self.bulletIconNames.hash ^ (_bulletType ? 0xf : 0x0) ^ (_allowsSelection ? 0xf : 0x0) ^ (_pinNavigationContainer ? 0xf : 0x0);
|
||||
return super.hash ^ self.items.hash ^ self.bulletIconNames.hash ^ self.bottomPadding.hash ^ (_bulletType ? 0xf : 0x0) ^ (_allowsSelection ? 0xf : 0x0) ^ (_pinNavigationContainer ? 0xf : 0x0);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -30,7 +30,10 @@
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
#import <HealthKit/HealthKit.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
@@ -271,6 +274,7 @@ requests access to these HealthKit types.
|
||||
|
||||
See also: `requestedHealthKitTypesForWriting`.
|
||||
*/
|
||||
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
@property (nonatomic, copy, readonly, nullable) NSSet<HKObjectType *> *requestedHealthKitTypesForReading;
|
||||
|
||||
/**
|
||||
@@ -283,7 +287,7 @@ requests access to these HealthKit types.
|
||||
See also: `requestedHealthKitTypesForReading`.
|
||||
*/
|
||||
@property (nonatomic, copy, readonly, nullable) NSSet<HKObjectType *> *requestedHealthKitTypesForWriting;
|
||||
|
||||
#endif
|
||||
/**
|
||||
The set of permissions requested by the task.
|
||||
|
||||
|
||||
@@ -131,6 +131,15 @@ typedef NS_ENUM(NSInteger, ORKQuestionType) {
|
||||
*/
|
||||
ORKQuestionTypeSES,
|
||||
|
||||
/**
|
||||
In an age question, the participant can enter an age by using an age picker.
|
||||
*/
|
||||
ORKQuestionTypeAge,
|
||||
|
||||
/**
|
||||
In an age question, the participant can enter an age by using an age picker. ORKQuestionTypeYear will be used if the useYearForResult property of the question's ORKAgeAnswerFormat is set to true.
|
||||
*/
|
||||
ORKQuestionTypeYear
|
||||
} ORK_ENUM_AVAILABLE;
|
||||
|
||||
|
||||
@@ -391,7 +400,6 @@ ORK_EXTERN ORKHeadphoneTypeIdentifier const ORKHeadphoneTypeIdentifierAirPodsPro
|
||||
|
||||
/// AirPods Max
|
||||
ORK_EXTERN ORKHeadphoneTypeIdentifier const ORKHeadphoneTypeIdentifierAirPodsMax;
|
||||
|
||||
/// Lightning and Audio Jack Earpods
|
||||
ORK_EXTERN ORKHeadphoneTypeIdentifier const ORKHeadphoneTypeIdentifierEarPods;
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ ORKHeadphoneTypeIdentifier const ORKHeadphoneTypeIdentifierAirPodsPro = @"AIRPOD
|
||||
ORKHeadphoneTypeIdentifier const ORKHeadphoneTypeIdentifierAirPodsProGen2 = @"AIRPODSPROV2";
|
||||
|
||||
ORKHeadphoneTypeIdentifier const ORKHeadphoneTypeIdentifierAirPodsMax = @"AIRPODSMAX";
|
||||
|
||||
ORKHeadphoneTypeIdentifier const ORKHeadphoneTypeIdentifierEarPods = @"EARPODS";
|
||||
|
||||
ORKHeadphoneTypeIdentifier const ORKHeadphoneTypeIdentifierUnknown = @"UNKNOWN";
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
*/
|
||||
|
||||
|
||||
@import UIKit;
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <ResearchKit/ORKDefines.h>
|
||||
#import <ResearchKit/ORKTypes.h>
|
||||
|
||||
|
||||
@@ -8,3 +8,4 @@ RUN_CLANG_STATIC_ANALYZER = YES
|
||||
|
||||
SUPPORTS_MACCATALYST = NO
|
||||
TARGETED_DEVICE_FAMILY = 1
|
||||
DEBUG_INFORMATION_FORMAT = dwarf
|
||||
|
||||
@@ -23,13 +23,20 @@ PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*] =
|
||||
SWIFT_VERSION = 5.0
|
||||
CLANG_STATIC_ANALYZER_MODE = deep
|
||||
|
||||
ORK_FRAMEWORK_VERSION_NUMBER = 3.0
|
||||
ORK_FRAMEWORK_VERSION_NUMBER = 3.1.1
|
||||
|
||||
ORK_FRAMEWORK_BUILD_NUMBER = $(ORK_FRAMEWORK_BUILD_NUMBER_CI_$(CI)) // ORK_FRAMEWORK_BUILD_NUMBER_CI_TRUE or ORK_FRAMEWORK_BUILD_NUMBER_CI_
|
||||
ORK_FRAMEWORK_BUILD_NUMBER_CI_TRUE = $(CI_BUILD_NUMBER)
|
||||
ORK_FRAMEWORK_BUILD_NUMBER_CI_FALSE = $(ORK_FRAMEWORK_VERSION_NUMBER) // When not building in CI, assume build and version number are the same
|
||||
ORK_FRAMEWORK_BUILD_NUMBER_CI_ = $(ORK_FRAMEWORK_BUILD_NUMBER_CI_FALSE)
|
||||
|
||||
// Some CLLocationManager API calls would trigger authorization to use location. The presence of those
|
||||
// API calls in ResearchKit **at compile time** mean apps that link ResearchKit also need Info.plist entries
|
||||
// for NSLocationAlwaysAndWhenInUseUsageDescription and NSLocationWhenInUseUsageDescription.
|
||||
// If your app doesn't use ORKLocationRecorder and doesn't specify these Info.plist strings, disable
|
||||
// ResearchKit's CLLocationManager authorization
|
||||
ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION = 1
|
||||
|
||||
// Control whether ResearchKit compiles out CLLocationManager calls that would request authorization for location
|
||||
// ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION=0 compiles out the feature
|
||||
// ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION=1 compiles RK with the feature intact
|
||||
@@ -37,6 +44,27 @@ ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS = $(ORK_FEATURE_CLLOCATIONMANAGER_DEFI
|
||||
ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS_0 = ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION=0
|
||||
ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS_1 = ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION=1
|
||||
|
||||
|
||||
// Some HealthKit API calls used within the framework require your app to disclose using HealthKit and provide a reason during app store review.
|
||||
// If your app does not use HealthKit or any of the ResearchKit HealthKit APIs, disable ResearchKit's HealthKit authorization.
|
||||
ORK_FEATURE_HEALTHKIT_AUTHORIZATION = 1
|
||||
|
||||
// GCC Preprocessor definitions
|
||||
ORK_FEATURE_HEALTHKIT_DEFINITIONS_GCC = $(ORK_FEATURE_HEALTHKIT_DEFINITIONS_GCC_$(ORK_FEATURE_HEALTHKIT_AUTHORIZATION))
|
||||
ORK_FEATURE_HEALTHKIT_DEFINITIONS_GCC_0 = ORK_FEATURE_HEALTHKIT_AUTHORIZATION=0
|
||||
ORK_FEATURE_HEALTHKIT_DEFINITIONS_GCC_1 = ORK_FEATURE_HEALTHKIT_AUTHORIZATION=1
|
||||
|
||||
// Swift active compilation conditions
|
||||
ORK_FEATURE_HEALTHKIT_DEFINITIONS_SWIFT = $(ORK_FEATURE_HEALTHKIT_DEFINITIONS_SWIFT_$(ORK_FEATURE_HEALTHKIT_AUTHORIZATION))
|
||||
ORK_FEATURE_HEALTHKIT_DEFINITIONS_SWIFT_0 =
|
||||
ORK_FEATURE_HEALTHKIT_DEFINITIONS_SWIFT_1 = ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
|
||||
#include? "../../../../xcconfig/ResearchKit-Shared.xcconfig"
|
||||
|
||||
|
||||
#include? "samples/ORKCatalog/ResearchKit-Shared.xcconfig"
|
||||
#include? "../xcconfig/ResearchKit-Shared.xcconfig"
|
||||
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) GLES_SILENCE_DEPRECATION=1 $(ORK_GCC_PREPROCESSOR_DEFINITIONS) $(ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS)
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) GLES_SILENCE_DEPRECATION=1 $(ORK_GCC_PREPROCESSOR_DEFINITIONS) $(ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS) $(ORK_FEATURE_HEALTHKIT_DEFINITIONS_GCC)
|
||||
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) $(ORK_FEATURE_HEALTHKIT_DEFINITIONS_SWIFT)
|
||||
|
||||
@@ -3,3 +3,5 @@
|
||||
//
|
||||
|
||||
#include "ResearchKitActiveTask-Shared.xcconfig"
|
||||
|
||||
DEBUG_INFORMATION_FORMAT = dwarf
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
#include "ResearchKitTests-Shared.xcconfig"
|
||||
|
||||
SWIFT_OBJC_BRIDGING_HEADER = ResearchKitTests/ResearchKitTests-Bridging-Header.h
|
||||
|
||||
DEBUG_INFORMATION_FORMAT = dwarf
|
||||
|
||||
@@ -20,6 +20,41 @@ ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS = $(ORK_FEATURE_CLLOCATIONMANAGER_DEFI
|
||||
ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS_0 = ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION=0
|
||||
ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS_1 = ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION=1
|
||||
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) $(ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS)
|
||||
|
||||
// Some CLLocationManager API calls would trigger authorization to use location. The presence of those
|
||||
// API calls in ResearchKit **at compile time** mean apps that link ResearchKit also need Info.plist entries
|
||||
// for NSLocationAlwaysAndWhenInUseUsageDescription and NSLocationWhenInUseUsageDescription.
|
||||
// If your app doesn't use ORKLocationRecorder and doesn't specify these Info.plist strings, disable
|
||||
// ResearchKit's CLLocationManager authorization
|
||||
ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION = 1
|
||||
|
||||
// Some HealthKit API calls used within the framework require your app to disclose using HealthKit and provide a reason during app store review.
|
||||
// If your app does not use HealthKit or any of the ResearchKit HealthKit APIs, disable ResearchKit's HealthKit authorization.
|
||||
ORK_FEATURE_HEALTHKIT_AUTHORIZATION = 1
|
||||
|
||||
// GCC Preprocessor definitions
|
||||
ORK_FEATURE_HEALTHKIT_DEFINITIONS_GCC = $(ORK_FEATURE_HEALTHKIT_DEFINITIONS_GCC_$(ORK_FEATURE_HEALTHKIT_AUTHORIZATION))
|
||||
ORK_FEATURE_HEALTHKIT_DEFINITIONS_GCC_0 = ORK_FEATURE_HEALTHKIT_AUTHORIZATION=0
|
||||
ORK_FEATURE_HEALTHKIT_DEFINITIONS_GCC_1 = ORK_FEATURE_HEALTHKIT_AUTHORIZATION=1
|
||||
|
||||
ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS_GCC = $(ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS_GCC_$(ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION))
|
||||
ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS_GCC_0 = ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION=0
|
||||
ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS_GCC_1 = ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION=1
|
||||
|
||||
// Swift active compilation conditions
|
||||
ORK_FEATURE_HEALTHKIT_DEFINITIONS_SWIFT = $(ORK_FEATURE_HEALTHKIT_DEFINITIONS_SWIFT_$(ORK_FEATURE_HEALTHKIT_AUTHORIZATION))
|
||||
ORK_FEATURE_HEALTHKIT_DEFINITIONS_SWIFT_0 =
|
||||
|
||||
ORK_FEATURE_HEALTHKIT_DEFINITIONS_SWIFT_1 = ORK_FEATURE_HEALTHKIT_AUTHORIZATION
|
||||
|
||||
ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS_SWIFT = $(ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS_SWIFT_$(ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION))
|
||||
ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS_SWIFT_0 =
|
||||
ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS_SWIFT_1 = ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
||||
|
||||
#include? "../xcconfig/ResearchKit-Shared.xcconfig"
|
||||
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) GLES_SILENCE_DEPRECATION=1 $(ORK_FEATURE_HEALTHKIT_DEFINITIONS_GCC) $(ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS_GCC)
|
||||
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) $(ORK_FEATURE_HEALTHKIT_DEFINITIONS_SWIFT) $(ORK_FEATURE_CLLOCATIONMANAGER_DEFINITIONS_SWIFT)
|
||||
|
||||
|
||||
|
||||
@@ -3,3 +3,5 @@
|
||||
//
|
||||
|
||||
#include "ResearchKitUI-iOS-Shared.xcconfig"
|
||||
|
||||
DEBUG_INFORMATION_FORMAT = dwarf
|
||||
|
||||
@@ -609,7 +609,7 @@
|
||||
"ENVIRONMENTSPL_UNIT" = "dBA";
|
||||
"ENVIRONMENTSPL_CALCULATING" = "Measuring…";
|
||||
"ENVIRONMENTSPL_THRESHOLD" = "Threshold: %@ dBA";
|
||||
"ENVIRONMENTSPL_OK" = "Background Noise OK";
|
||||
"ENVIRONMENTSPL_OK" = "Good";
|
||||
"ENVIRONMENTSPL_NOISE" = "Too Loud";
|
||||
"ENVIRONMENTSPL_TITLE_2" = "Find a Quiet Place";
|
||||
"ENVIRONMENTSPL_INTRO_TEXT_2" = "For accurate results, this task should be completed in a quiet location. Once the background noise measurement reading is completed, you may continue.";
|
||||
@@ -794,3 +794,21 @@
|
||||
"KNEE_RANGE_OF_MOTION_TOUCH_ANYWHERE_STEP_INSTRUCTION_RIGHT" = "Place your device on your right knee.\n\nTap the screen and extend your right knee as far as you can.\n";
|
||||
"KNEE_RANGE_OF_MOTION_SPOKEN_INSTRUCTION_LEFT" = "When you are done, return your left knee to the start position.\n\nThen tap anywhere.";
|
||||
"KNEE_RANGE_OF_MOTION_SPOKEN_INSTRUCTION_RIGHT" = "When you are done, return your right knee to the start position.\n\nThen tap anywhere.";
|
||||
|
||||
/* Family History */
|
||||
"FAMILY_HISTORY_I_DONT_KNOW" = "I don't know";
|
||||
"FAMILY_HISTORY_CONDITIONS_FORM_ITEM_TEXT" = "Have they been diagnosed with any of the following diseases or health conditions?";
|
||||
"FAMILY_HISTORY_CONDITIONS_STEP_TITLE" = "Health Conditions";
|
||||
"FAMILY_HISTORY_CONDITIONS_STEP_DESCRIPTION" = "Answer these questions to the best of your ability";
|
||||
"FAMILY_HISTORY_COMPLETION_STEP_TITLE" = "Task Complete";
|
||||
"FAMILY_HISTORY_NONE_OF_THE_ABOVE" = "None of the above";
|
||||
"FAMILY_HISTORY_PREFER_NOT_TO_ANSWER" = "I prefer not to answer";
|
||||
"FAMILY_HISTORY_CONDITIONS" = "Conditions";
|
||||
"FAMILY_HISTORY_NONE_SELECTED" = "None selected";
|
||||
"FAMILY_HISTORY_EDIT_ENTRY" = "Edit Entry";
|
||||
"FAMILY_HISTORY_DELETE_ENTRY_TITLE" = "Are you sure you want to delete this entry from your Family Health History?";
|
||||
"FAMILY_HISTORY_DELETE_ENTRY" = "Delete Entry";
|
||||
"FAMILY_HISTORY_CANCEL" = "Cancel";
|
||||
"FAMILY_HISTORY_ADD" = "Add %@";
|
||||
"FAMILY_HISTORY_CONDITIONS_STEP_DESCRIPTION_TEMP" = "Confirm any diagnosed diseases or health conditions.";
|
||||
"AX_FAMILY_HISTORY_EDIT_BUTTON" = "Edit button";
|
||||
|
||||
@@ -73,13 +73,8 @@ static NSArray <ORKFormItem*> *ORKRegistrationFormItems(ORKRegistrationStepOptio
|
||||
answerFormat.autocapitalizationType = UITextAutocapitalizationTypeNone;
|
||||
answerFormat.autocorrectionType = UITextAutocorrectionTypeNo;
|
||||
answerFormat.spellCheckingType = UITextSpellCheckingTypeNo;
|
||||
|
||||
if (@available(iOS 12.0, *)) {
|
||||
answerFormat.textContentType = UITextContentTypeNewPassword;
|
||||
} else {
|
||||
answerFormat.textContentType = UITextContentTypePassword;
|
||||
}
|
||||
|
||||
answerFormat.textContentType = UITextContentTypeOneTimeCode;
|
||||
|
||||
ORKFormItem *item = [[ORKFormItem alloc] initWithIdentifier:ORKRegistrationFormItemIdentifierPassword
|
||||
text:ORKLocalizedString(@"PASSWORD_FORM_ITEM_TITLE", nil)
|
||||
answerFormat:answerFormat
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>C617.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
<key>NSPrivacyTrackingDomains</key>
|
||||
<array/>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyCollectedDataType</key>
|
||||
<string>NSPrivacyCollectedDataTypePhotosorVideos</string>
|
||||
<key>NSPrivacyCollectedDataTypeLinked</key>
|
||||
<true/>
|
||||
<key>NSPrivacyCollectedDataTypeTracking</key>
|
||||
<false/>
|
||||
<key>NSPrivacyCollectedDataTypePurposes</key>
|
||||
<array>
|
||||
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyCollectedDataType</key>
|
||||
<string>NSPrivacyCollectedDataTypeSensitiveInfo</string>
|
||||
<key>NSPrivacyCollectedDataTypeLinked</key>
|
||||
<false/>
|
||||
<key>NSPrivacyCollectedDataTypeTracking</key>
|
||||
<false/>
|
||||
<key>NSPrivacyCollectedDataTypePurposes</key>
|
||||
<array>
|
||||
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyCollectedDataType</key>
|
||||
<string>NSPrivacyCollectedDataTypeHealth</string>
|
||||
<key>NSPrivacyCollectedDataTypeLinked</key>
|
||||
<true/>
|
||||
<key>NSPrivacyCollectedDataTypeTracking</key>
|
||||
<false/>
|
||||
<key>NSPrivacyCollectedDataTypePurposes</key>
|
||||
<array>
|
||||
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyCollectedDataType</key>
|
||||
<string>NSPrivacyCollectedDataTypePreciseLocation</string>
|
||||
<key>NSPrivacyCollectedDataTypeLinked</key>
|
||||
<true/>
|
||||
<key>NSPrivacyCollectedDataTypeTracking</key>
|
||||
<false/>
|
||||
<key>NSPrivacyCollectedDataTypePurposes</key>
|
||||
<array>
|
||||
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,19 +0,0 @@
|
||||
# Active tasks
|
||||
|
||||
Present a specific question and collect an answer.
|
||||
|
||||
## Topics
|
||||
|
||||
### Essentials
|
||||
|
||||
- ``ORKActiveStep``
|
||||
- ``ORKActiveStepViewController``
|
||||
|
||||
### Audio
|
||||
|
||||
- ``ORKInvalidDBHLValue``
|
||||
- ``ORKAudiometryTimestampProvider``
|
||||
- ``ORKAudioChannel``
|
||||
- ``ORKSpeechRecognizerLocale``
|
||||
- ``ORKAudiometryProtocol``
|
||||
|
||||
@@ -4,12 +4,21 @@ Present a specific question and collect an answer.
|
||||
|
||||
## Topics
|
||||
|
||||
### Age
|
||||
|
||||
- ``ORKAgeAnswerFormat``
|
||||
|
||||
### Color Choice
|
||||
|
||||
- ``ORKColorChoiceAnswerFormat``
|
||||
- ``ORKColorChoice``
|
||||
|
||||
### Essentials
|
||||
|
||||
- ``ORKAnswerFormat``
|
||||
- ``ORKNumericPrecision``
|
||||
|
||||
### height, and weight
|
||||
### Height and Weight
|
||||
|
||||
- ``ORKHeightAnswerFormat``
|
||||
- ``ORKWeightAnswerFormat``
|
||||
|
||||
@@ -11,11 +11,10 @@ Obtain a participant's consent to collect research data.
|
||||
- ``ORKCustomSignatureAccessoryViewDelegate``
|
||||
- ``ORKCustomSignatureAccessoryViewProtocol``
|
||||
- ``ORKCustomSignatureAccessoryViewProvider``
|
||||
- ``ORKCustomSignatureFooterViewStatusDelegate``
|
||||
- ``ORKConsentSectionType``
|
||||
|
||||
### Signature acquisition
|
||||
|
||||
- ``ORKSignatureView``
|
||||
- ``ORKConsentSignature``
|
||||
- ``ORKSignatureViewDelegate``
|
||||
- ``ORKSignatureFormatter``
|
||||
- ``ORKHTMLPDFWriter``
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# Constants
|
||||
|
||||
Constants utilized throughout ResearchKit.
|
||||
|
||||
## Topics
|
||||
|
||||
### Constants
|
||||
|
||||
- ``CheckmarkViewDimension``
|
||||
- ``ORKAuxiliaryImageTintColorKey``
|
||||
- ``ORKBackgroundColorKey``
|
||||
- ``ORKBlueHighlightColorKey``
|
||||
- ``ORKBodyToBodyPaddingStandard``
|
||||
- ``ORKBodyToBodyParagraphPaddingStandard``
|
||||
- ``ORKBulletItemTextColorKey``
|
||||
- ``ORKCaptionTextColorKey``
|
||||
- ``ORKCardDefaultBorderWidth``
|
||||
- ``ORKCardDefaultCornerRadii``
|
||||
- ``ORKCardDefaultFontSize``
|
||||
- ``ORKConsentBackgroundColorKey``
|
||||
- ``ORKDarkTintColorKey``
|
||||
- ``ORKDoneButtonPressedKey``
|
||||
- ``ORKEffectViewOpacityHidden``
|
||||
- ``ORKEffectViewOpacityVisible``
|
||||
- ``ORKFormStepLargeTextMinimumHeaderHeight``
|
||||
- ``ORKFormStepMinimumHeaderHeight``
|
||||
- ``ORKImageChoiceButtonCornerRadii``
|
||||
- ``ORKLightTintColorKey``
|
||||
- ``ORKNavigationContainerColorKey``
|
||||
- ``ORKNavigationContainerShadowColorKey``
|
||||
- ``ORKProgressLabelColorKey``
|
||||
- ``ORKQuestionStepMinimumHeaderHeight``
|
||||
- ``ORKResetDoneButtonKey``
|
||||
- ``ORKScreenMetricMaxDimension``
|
||||
- ``ORKSignatureColorKey``
|
||||
- ``ORKStepContainerTitleToBodyTopPaddingStandard``
|
||||
- ``ORKStepContentIconImageViewDimension``
|
||||
- ``ORKStepTopContentImageChangedKey``
|
||||
- ``ORKSurveyItemMargin``
|
||||
- ``ORKSurveyTableContainerLeftRightPadding``
|
||||
- ``ORKToolBarTintColorKey``
|
||||
- ``ORKTopContentImageViewBackgroundColorKey``
|
||||
- ``ORKiPadBackgroundViewBottomPadding``
|
||||
- ``ORKiPadBackgroundViewColorKey``
|
||||
- ``ORKiPadBackgroundViewCornerRadius``
|
||||
- ``ORKiPadBackgroundViewLeftRightPadding``
|
||||
@@ -0,0 +1,17 @@
|
||||
# Enumerations
|
||||
|
||||
Enumerations utilized throughout ResearchKit.
|
||||
|
||||
## Topics
|
||||
|
||||
### Enumerations
|
||||
|
||||
- ``ORKAudioChannel``
|
||||
- ``ORKBodySagittal``
|
||||
- ``ORKHeadphoneTypeIdentifier``
|
||||
- ``ORKRequestPermissionsState``
|
||||
- ``ORKSampleJSONOptions``
|
||||
- ``ORKScreenMetric``
|
||||
- ``ORKScreenType``
|
||||
- ``ORKSpeechRecognizerLocale``
|
||||
- ``ORKTaskFinishReason``
|
||||
@@ -0,0 +1,31 @@
|
||||
# Helper Functions
|
||||
|
||||
Helper Functions utilized throughout ResearchKit.
|
||||
|
||||
## Topics
|
||||
|
||||
### Helper Functions
|
||||
|
||||
- ``ORKCardLeftRightMarginForWindow``
|
||||
- ``ORKColor``
|
||||
- ``ORKColorSetColorForKey``
|
||||
- ``ORKGetMetricForWindow``
|
||||
- ``ORKGetVerticalScreenTypeForWindow``
|
||||
- ``ORKNeedWideScreenDesign``
|
||||
- ``ORKScrollIndicatorInsetsForScrollView``
|
||||
- ``ORKStandardFullScreenLayoutMarginsForView``
|
||||
- ``ORKStandardHorizontalMarginForView``
|
||||
- ``ORKStandardLayoutMarginsForTableViewCell``
|
||||
- ``ORKStandardLeftMarginForTableViewCell``
|
||||
- ``ORKStepContainerExtendedLeftRightPaddingForWindow``
|
||||
- ``ORKStepContainerFirstItemTopPaddingForWindow``
|
||||
- ``ORKStepContainerLeftRightPaddingForWindow``
|
||||
- ``ORKStepContainerTitleToBodyTopPaddingForWindow``
|
||||
- ``ORKStepContainerTitleToBulletTopPaddingForWindow``
|
||||
- ``ORKStepContainerTopContentHeightForWindow``
|
||||
- ``ORKStepContainerTopPaddingForWindow``
|
||||
- ``ORKTaskProgressMake``
|
||||
- ``ORKTaskTotalProgressMake``
|
||||
- ``ORKTitleLabelFontTextStyleForWindow``
|
||||
- ``ORKUpdateScrollViewBottomInset``
|
||||
- ``ORKWidthForSignatureView``
|
||||
@@ -15,6 +15,10 @@ Obtain information from a step.
|
||||
|
||||
- ``ORKTaskResultSource``
|
||||
|
||||
### Family History
|
||||
|
||||
- ``ORKFamilyHistoryResult``
|
||||
|
||||
### File storage
|
||||
|
||||
- ``ORKFileResult``
|
||||
@@ -25,14 +29,6 @@ Obtain information from a step.
|
||||
- ``ORKSignatureResult``
|
||||
- ``ORKConsentSignatureResult``
|
||||
|
||||
### Hearing
|
||||
|
||||
- ``ORKdBHLToneAudiometryResult``
|
||||
- ``ORKEnvironmentSPLMeterResult``
|
||||
- ``ORKToneAudiometryResult``
|
||||
- ``ORKSpeechInNoiseResult``
|
||||
- ``ORKSpeechRecognitionResult``
|
||||
|
||||
### Data collection
|
||||
|
||||
- ``ORKCollector``
|
||||
@@ -40,31 +36,8 @@ Obtain information from a step.
|
||||
- ``ORKHealthCorrelationCollector``
|
||||
- ``ORKDataCollectionManager``
|
||||
- ``ORKDataCollectionManagerDelegate``
|
||||
- ``ORKRangeOfMotionResult``
|
||||
- ``ORKReactionTimeResult``
|
||||
- ``ORKBundleAsset``
|
||||
|
||||
### Dexterity
|
||||
|
||||
- ``ORKTimedWalkResult``
|
||||
- ``ORKTowerOfHanoiResult``
|
||||
- ``ORKTrailmakingResult``
|
||||
- ``ORKHolePegTestResult``
|
||||
- ``ORKTappingIntervalResult``
|
||||
- ``ORKHolePegTestResult``
|
||||
- ``ORKNormalizedReactionTimeResult``
|
||||
- ``ORKPSATResult``
|
||||
|
||||
### Memory
|
||||
|
||||
- ``ORKSpatialSpanMemoryResult``
|
||||
|
||||
### Vision
|
||||
|
||||
- ``ORKStroopResult``
|
||||
- ``ORKAccuracyStroopResult``
|
||||
- ``ORKAmslerGridResult``
|
||||
|
||||
### Surveys
|
||||
|
||||
- ``ORKQuestionResult``
|
||||
@@ -88,7 +61,3 @@ Obtain information from a step.
|
||||
### Web
|
||||
|
||||
- ``ORKWebViewStepResult``
|
||||
|
||||
### 3-D models
|
||||
|
||||
- ``ORKUSDZModelManagerResult``
|
||||
|
||||
@@ -11,26 +11,18 @@ Using ResearchKit, you can build apps that obtain consent, give instructions, pr
|
||||
### Essentials
|
||||
|
||||
- ``ORKStep``
|
||||
- ``ORKStepViewController``
|
||||
- ``ORKStepViewControllerDelegate``
|
||||
|
||||
### Active steps
|
||||
|
||||
- ``ORKActiveStep``
|
||||
- ``ORKActiveStepViewController``
|
||||
- ``ORKMotionActivityCollector``
|
||||
- ``ORKMotionActivityPermissionType``
|
||||
- ``ORKHolePegTestSample``
|
||||
- ``ORKEnvironmentSPLMeterStep``
|
||||
- ``ORKBodySagittal``
|
||||
|
||||
### Authentication and consent steps
|
||||
|
||||
- ``ORKLoginStep``
|
||||
- ``ORKLoginStepViewController``
|
||||
- ``ORKSignatureStep``
|
||||
- ``ORKVerificationStep``
|
||||
- ``ORKVerificationStepViewController``
|
||||
- ``ORKLoginFormItemIdentifierEmail``
|
||||
- ``ORKLoginFormItemIdentifierPassword``
|
||||
- ``ORKKeychainWrapper``
|
||||
@@ -52,18 +44,22 @@ Using ResearchKit, you can build apps that obtain consent, give instructions, pr
|
||||
- ``ORKConsentReviewStep``
|
||||
- ``ORKConsentSharingStep``
|
||||
- ``ORKCompletionStep``
|
||||
- ``ORKCompletionStepViewController``
|
||||
- ``ORKCompletionStepIdentifier``
|
||||
|
||||
### Custom steps
|
||||
|
||||
- ``ORKCustomStep``
|
||||
- ``ORKCustomStepViewController``
|
||||
|
||||
### Family History
|
||||
|
||||
- ``ORKFamilyHistoryStep``
|
||||
- ``ORKConditionStepConfiguration``
|
||||
- ``ORKHealthCondition``
|
||||
- ``ORKRelatedPerson``
|
||||
- ``ORKRelativeGroup``
|
||||
|
||||
### Form steps
|
||||
|
||||
- ``ORKFormStep``
|
||||
- ``ORKFormStepViewController``
|
||||
- ``ORKBodyItem``
|
||||
- ``ORKBulletType``
|
||||
- ``ORKBodyItemStyle``
|
||||
@@ -76,43 +72,31 @@ Using ResearchKit, you can build apps that obtain consent, give instructions, pr
|
||||
|
||||
### Image and 3D model steps
|
||||
|
||||
- ``ORK3DModelStep``
|
||||
- ``ORK3DModelManager``
|
||||
- ``ORKUSDZModelManager``
|
||||
- ``ORK3DModelManagerProtocol``
|
||||
- ``ORKFrontFacingCameraStep``
|
||||
- ``ORKImageCaptureStep``
|
||||
- ``ORKPlaybackButton``
|
||||
|
||||
### Location steps
|
||||
|
||||
- ``ORKLocation``
|
||||
- ``ORKLocationPermissionType``
|
||||
- ``ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION``
|
||||
|
||||
### Passcode steps
|
||||
|
||||
- ``ORKPasscodeStep``
|
||||
- ``ORKPasscodeViewController``
|
||||
- ``ORKPasscodeDelegate``
|
||||
- ``ORKPasscodeFlow``
|
||||
- ``ORKPasscodeType``
|
||||
|
||||
### PDF and page steps
|
||||
|
||||
- ``ORKPDFViewerStep``
|
||||
- ``ORKPDFViewerStepViewController``
|
||||
- ``ORKPageStep``
|
||||
- ``ORKPageStepViewController``
|
||||
- ``ORKPDFViewerActionBarOption``
|
||||
|
||||
### Question and instruction steps
|
||||
|
||||
- ``ORKQuestionStep``
|
||||
- ``ORKInstructionStep``
|
||||
- ``ORKInstructionStepViewController``
|
||||
- ``ORKLearnMoreInstructionStep``
|
||||
- ``ORKLearnMoreStepViewController``
|
||||
- ``ORKNavigablePageStep``
|
||||
|
||||
### Registration steps
|
||||
@@ -130,8 +114,6 @@ Using ResearchKit, you can build apps that obtain consent, give instructions, pr
|
||||
### Review steps
|
||||
|
||||
- ``ORKReviewStep``
|
||||
- ``ORKReviewViewController``
|
||||
- ``ORKReviewViewControllerDelegate``
|
||||
|
||||
### Step recording
|
||||
|
||||
@@ -142,7 +124,6 @@ Using ResearchKit, you can build apps that obtain consent, give instructions, pr
|
||||
### Table steps
|
||||
|
||||
- ``ORKTableStep``
|
||||
- ``ORKTableStepViewController``
|
||||
- ``ORKTableStepSource``
|
||||
|
||||
### Video steps
|
||||
@@ -157,19 +138,12 @@ Using ResearchKit, you can build apps that obtain consent, give instructions, pr
|
||||
### Wait steps
|
||||
|
||||
- ``ORKWaitStep``
|
||||
- ``ORKWaitStepViewController``
|
||||
|
||||
### Web steps
|
||||
|
||||
- ``ORKWebViewStep``
|
||||
- ``ORKWebViewStepDelegate``
|
||||
- ``ORKWebViewStepViewController``
|
||||
|
||||
### Other steps
|
||||
|
||||
- ``ORKSecondaryTaskStep``
|
||||
- ``ORKSkipStepNavigationRule``
|
||||
- ``ORKTouchAnywhereStep``
|
||||
- ``ORKTouchAnywhereStepViewController``
|
||||
- ``ORKAccuracyStroopStep``
|
||||
|
||||
|
||||
@@ -13,44 +13,20 @@ A task can be a simple ordered sequence of steps, or be dynamic with previous re
|
||||
- ``ORKTask``
|
||||
- ``ORKOrderedTask``
|
||||
- ``ORKNavigableOrderedTask``
|
||||
- ``SwiftUIViewFactory``
|
||||
|
||||
### View controllers
|
||||
|
||||
- ``ORKTaskViewController``
|
||||
- ``ORKTaskViewControllerDelegate``
|
||||
- ``ORKTaskViewControllerFinishReason``
|
||||
- ``ORKTaskViewControllerReviewMode``
|
||||
|
||||
### Audio
|
||||
|
||||
- ``ORKAudiometryStimulus``
|
||||
- ``ORKAudioRecorderConfiguration``
|
||||
- ``ORKToneAudiometrySample``
|
||||
- ``ORKdBHLToneAudiometryFrequencySample``
|
||||
- ``ORKdBHLTaskContext``
|
||||
- ``ORKdBHLToneAudiometryUnit``
|
||||
|
||||
### Dexterity
|
||||
|
||||
- ``ORKPredefinedTaskHandOption``
|
||||
- ``ORKPredefinedTaskOption``
|
||||
- ``ORKPredefinedTaskLimbOption``
|
||||
- ``ORKPSATSample``
|
||||
- ``ORKPSATPresentationMode``
|
||||
- ``ORKTappingSample``
|
||||
- ``ORKTappingButtonIdentifier``
|
||||
- ``ORKTowerOfHanoiMove``
|
||||
- ``ORKTrailmakingTap``
|
||||
- ``ORKTrailMakingTypeIdentifier``
|
||||
- ``ORKTremorActiveTaskOption``
|
||||
|
||||
### Memory
|
||||
|
||||
- ``ORKSpatialSpanMemoryGameRecord``
|
||||
- ``ORKSpatialSpanMemoryGameStatus``
|
||||
- ``ORKSpatialSpanMemoryGameTouchSample``
|
||||
|
||||
### Navigation
|
||||
|
||||
- ``ORKStepNavigationRule``
|
||||
@@ -63,7 +39,6 @@ A task can be a simple ordered sequence of steps, or be dynamic with previous re
|
||||
- ``ORKStepModifier``
|
||||
- ``ORKResultPredicateTaskIdentifierVariableName``
|
||||
- ``ORKNullStepIdentifier``
|
||||
- ``ORKStepViewControllerNavigationDirection``
|
||||
- ``ORKKeyValueStepModifier``
|
||||
- ``ORKResultPredicate``
|
||||
- ``ORKResultSelector``
|
||||
@@ -73,4 +48,3 @@ A task can be a simple ordered sequence of steps, or be dynamic with previous re
|
||||
- ``ORKTaskProgress``
|
||||
- ``ORKTaskTotalProgress``
|
||||
- ``ORKProgressIndicatorType``
|
||||
- ``ORKTaskViewControllerProgressMode``
|
||||
|
||||
@@ -38,4 +38,19 @@ capabilities of frameworks such as HealthKit and CoreMotion.
|
||||
|
||||
- <doc:Consent>
|
||||
- <doc:Surveys>
|
||||
- <doc:ActiveTasks>
|
||||
- <doc:Understanding-Active-Tasks>
|
||||
|
||||
### Articles
|
||||
|
||||
- <doc:Conditional-Logic-in-ResearchKit>
|
||||
- <doc:Creating-Surveys>
|
||||
- <doc:Family-History-Step>
|
||||
- <doc:Obtaining-Consent>
|
||||
- <doc:Setting-up-Your-Project-to-Use-ResearchKit>
|
||||
- <doc:Understanding-Active-Tasks>
|
||||
|
||||
### Other
|
||||
|
||||
- <doc:Constants>
|
||||
- <doc:Enumerations>
|
||||
- <doc:Helper-Functions>
|
||||
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
# Conditional Logic in ResearchKit
|
||||
|
||||
How to use conditional logic for ResearchKit steps and forms.
|
||||
|
||||
## Understanding Conditional Logic
|
||||
|
||||
When presenting a survey or task, conditionally show specific content based on the participant's responses. ResearchKit provides two solutions for conditional logic.
|
||||
|
||||
- **Step Navigation rules**: Conditionally navigate to a specific step based on the participant's response.
|
||||
- **Form Item Visibility rules** - Conditionally hide or show specific form questions based on results from the same form or a form within another step.
|
||||
|
||||
|
||||
|
||||
### Navigating Steps Conditionally
|
||||
Review the following classes to conditionally navigate to or skip specific steps during an `ORKTask`.
|
||||
|
||||
- `ORKResultSelector` - A class that identifies a result within a set of task results.
|
||||
- `ORKResultPredicate` - Creates a predicate by accepting an `ORKResultSelector` and the expected result.
|
||||
- `ORKPredicateStepNavigationRule` - A class that determines what step to navigate to if a given `ORKResultPredicate` is true.
|
||||
- `ORKNavigableOrderedTask` - A subclass of the `ORKOrderedTask` that can accept one or more `ORKPredicateStepNavigationRule` objects and apply the expected conditional navigation.
|
||||
|
||||
|
||||
The task for this example includes the steps seen below.
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
The conditional logic is based on answering `Yes` or `No` for the first question ("Do you like Apples?"):
|
||||
|
||||
- **Answering yes**: navigates to the second screen to select your favorite apple.
|
||||
- **Answering no**: skips the second screen and navigates directly to the completion step.
|
||||
|
||||
```swift
|
||||
|
||||
//Construct Steps
|
||||
let boolFormStep = ORKFormStep(identifier: "FormStep1")
|
||||
boolFormStep.title = "Apple Task"
|
||||
boolFormStep.text = "Please answer the following question."
|
||||
|
||||
let boolAnswerFormat = ORKAnswerFormat.booleanAnswerFormat()
|
||||
let boolFormItem = ORKFormItem(identifier: "BooleanFormItemIdentifier",
|
||||
text: "Do you like Apples?",
|
||||
answerFormat: boolAnswerFormat)
|
||||
|
||||
boolFormStep.formItems = [boolFormItem]
|
||||
|
||||
let appleTextChoiceFormStep = appleTextChoiceFormStepExample()
|
||||
let completionStep = completionStepExample()
|
||||
|
||||
//Conditional Logic
|
||||
let boolResultSelector = ORKResultSelector(stepIdentifier: boolFormStep.identifier, resultIdentifier: boolFormItem.identifier)
|
||||
let boolResultPredicate = ORKResultPredicate.predicateForBooleanQuestionResult(with: boolResultSelector, expectedAnswer: false)
|
||||
let navigationRule = ORKPredicateStepNavigationRule(resultPredicatesAndDestinationStepIdentifiers: [ (boolResultPredicate, completionStep.identifier) ])
|
||||
|
||||
//Construct Navigable Task + Set Navigation Rule
|
||||
let navigableTask = ORKNavigableOrderedTask(identifier: "NavigableTaskIdentifier", steps: [formStep1, appleTextChoiceFormStep, completionStep])
|
||||
navigableTask.setNavigationRule(navigationRule, forTriggerStepIdentifier: formStep1.identifier)
|
||||
```
|
||||
|
||||
Selecting yes:
|
||||
|
||||
@Video(source: "conditional-logic-in-researchKit-step-yes")
|
||||
|
||||
Selecting no:
|
||||
|
||||
@Video(source: "conditional-logic-in-researchKit-step-no")
|
||||
|
||||
### Managing Form Item Visibility
|
||||
|
||||
Familiarize yourself with the following classes to conditionally hide or show a question based on results from questions within the same form.
|
||||
|
||||
- `ORKResultSelector` - A class that identifies a result within a set of task results.
|
||||
- `ORKResultPredicate` - Creates a predicate by accepting an `ORKResultSelector` and the expected result.
|
||||
- `ORKPredicateFormItemVisibilityRule` - A class that determines if the form item it's attached to is hidden or visible if a given `ORKResultPredicate` is true.
|
||||
|
||||
Following the previous example, use the same questions but now with both on the same page.
|
||||
|
||||
|
||||
- **Answering yes**: makes the apple choice question visible.
|
||||
- **Answering no**: hides the apple choice question if visible.
|
||||
|
||||
|
||||
```swift
|
||||
//Construct FormStep
|
||||
let formStep = ORKFormStep(identifier: "FormStep1")
|
||||
formStep.title = "Apple Task"
|
||||
formStep.text = "Please answer the following question."
|
||||
|
||||
let boolAnswerFormat = ORKAnswerFormat.booleanAnswerFormat()
|
||||
let boolFormItem = ORKFormItem(identifier: "BooleanFormItemIdentifier",
|
||||
text: "Do you like Apples?",
|
||||
answerFormat: boolAnswerFormat)
|
||||
|
||||
|
||||
let appleChoiceFormItem = appleChoiceFormItem()
|
||||
|
||||
formStep.formItems = [boolFormItem, appleChoiceFormItem]
|
||||
|
||||
let completionStep = completionStepExample()
|
||||
|
||||
//Conditional Logic
|
||||
let resultSelector: ORKResultSelector = .init(stepIdentifier: formStep.identifier, resultIdentifier: boolFormItem.identifier)
|
||||
let predicate = ORKResultPredicate.predicateForBooleanQuestionResult(with: resultSelector, expectedAnswer: true)
|
||||
let visibilityRule = ORKPredicateFormItemVisibilityRule(predicate: predicate)
|
||||
|
||||
appleChoiceFormItem.visibilityRule = visibilityRule
|
||||
|
||||
//Construct Navigable Task
|
||||
let navigableTask = ORKNavigableOrderedTask(identifier: "NavigableTaskIdentifier", steps: [formStep, completionStep])
|
||||
```
|
||||
|
||||
Selecting yes & no:
|
||||
|
||||
@Video(source: "conditional-logic-in-researchKit-formItem-yes-no")
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user