Compare commits

...

8 Commits

Author SHA1 Message Date
Pariece McKinney 5a96848943 Public release 3.1.1 2024-11-13 13:23:22 -05:00
simon-apple 45f7bce91f Added issue templates. (#1586) 2024-11-07 14:53:39 -08:00
Pariece McKinney 5c5d295bd5 Public release 3.1.0 2024-10-15 17:05:47 -04:00
Pariece McKinney b274d1f84e Update README.md 2024-10-15 08:23:23 -04:00
aplummer-apple 57427e8c7e Set “Enable Module Verifier” flag to “Yes” only in Release build configuration (#1579) 2024-08-08 18:21:18 -04:00
Louie 6cfb995d83 cleaning up unused strings (#1578) 2024-06-26 10:23:19 -07:00
Pariece McKinney c71d1a56dd Public release 3.0.1 2024-05-08 14:56:11 -04:00
Corey 6c24a7e922 ci: Add code integration testing to repo (#1569) 2024-04-10 14:33:32 -04:00
471 changed files with 9581 additions and 2019 deletions
+34
View File
@@ -0,0 +1,34 @@
---
name: Bug Report
about: File a bug to help us improve ResearchKit
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots or screen recordings**
Screenshots or screen recordings help us understand your problem with more clarity.
**ResearchKit Version**
- Version: [e.g. 3.0.1]
**Device Information**
- OS: [e.g. iOS 18.1/watchOS 11.0/visionOS 2.0]
- Device: [e.g. iPhone 16 Pro]
**Additional context**
Add surrounding context to bring more clarity to your problem.
+20
View File
@@ -0,0 +1,20 @@
---
name: Feature Request
about: Suggest an idea for ResearchKit
title: ''
labels: new feature
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
@@ -0,0 +1,10 @@
---
name: General Question
about: Ask a general question about ResearchKit's capabilities
title: ''
labels: question
assignees: ''
---
@@ -0,0 +1,10 @@
---
name: Technical Question
about: Ask a question about ResearchKit's API
title: ''
labels: tech question
assignees: ''
---
+26
View File
@@ -0,0 +1,26 @@
name: Build
on:
push:
branches: [ 'main', 'stable' ]
pull_request:
branches: [ 'main', 'stable' ]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
runs-on: macos-14
strategy:
matrix:
destination: ['platform=iOS\ Simulator,OS=17.4,name=iPhone\ 15\ Pro']
scheme: ['ResearchKit']
name: ${{ matrix.scheme }} Unit Tests
steps:
- uses: actions/checkout@v4
- name: Set Xcode Version
run: sudo xcode-select -s /Applications/Xcode_15.3.app
- name: Test
run: set -o pipefail && env NSUnbufferedIO=YES xcodebuild -verbose -workspace RKWorkspace.xcworkspace -scheme ${{ matrix.scheme }} -destination ${{ matrix.destination }} build test | xcpretty
+3
View File
@@ -1,3 +1,6 @@
![ResearchKit](https://github.com/user-attachments/assets/0384c1a6-ec67-45d3-be68-136a2e4cacff)
ResearchKit Framework
===========
+45
View File
@@ -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
+34
View File
@@ -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>
@@ -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
@@ -29,7 +29,7 @@
*/
@import CoreMotion;
#import <CoreMotion/CoreMotion.h>
NS_ASSUME_NONNULL_BEGIN
@@ -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
@@ -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
-1
View File
@@ -30,7 +30,6 @@
#import <UIKit/UIKit.h>
#import <HealthKit/HealthKit.h>
#import <ResearchKit/ORKStep.h>
+2
View File
@@ -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];
+184 -1
View File
@@ -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.
+451 -2
View File
@@ -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
+14 -6
View File
@@ -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()
+4
View File
@@ -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
+8 -1
View File
@@ -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];
+6 -2
View File
@@ -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.
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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.
+14 -3
View File
@@ -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;
+1 -1
View File
@@ -29,7 +29,7 @@
*/
@import Foundation;
#import <Foundation/Foundation.h>
#import <ResearchKit/ORKTypes.h>
-3
View File
@@ -32,9 +32,6 @@
#import "ORKDataLogger.h"
#import "ORKHelpers_Internal.h"
#import "CMMotionActivity+ORKJSONDictionary.h"
#import "HKSample+ORKJSONDictionary.h"
#include <sys/xattr.h>
-9
View File
@@ -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)
+1 -1
View File
@@ -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
+53
View File
@@ -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
+115
View File
@@ -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
+9
View File
@@ -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.
+9 -1
View File
@@ -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
+7 -2
View File
@@ -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
+2 -1
View File
@@ -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
+70
View File
@@ -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
+98
View File
@@ -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
+1
View File
@@ -559,3 +559,4 @@ NSNumberFormatter *ORKDecimalNumberFormatter(void) {
numberFormatter.usesGroupingSeparator = NO;
return numberFormatter;
}
+9 -1
View File
@@ -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) {
+1 -1
View File
@@ -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 {
+2
View File
@@ -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
+3
View File
@@ -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
+6
View File
@@ -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
+8 -3
View File
@@ -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.
+2 -1
View File
@@ -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
+8 -95
View File
@@ -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.
+3
View File
@@ -89,9 +89,12 @@
return nil;
}
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
- (NSSet<HKObjectType *> *)requestedHealthKitTypesForReading {
return nil;
}
#endif
- (ORKPermissionMask)requestedPermissionMask {
return ORKPermissionNone;
}
-32
View File
@@ -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 ()
/**
+87
View File
@@ -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
+190
View File
@@ -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 dont know"] || [[value lowercaseString] isEqual:@"i prefer not to answer"]);
}
@end
+89
View File
@@ -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
+129
View File
@@ -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
+1
View File
@@ -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
+1 -1
View File
@@ -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>
+10 -10
View File
@@ -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.
*/
+5
View File
@@ -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`.
+7 -2
View File
@@ -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
+5 -1
View File
@@ -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.
+9 -1
View File
@@ -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;
-1
View File
@@ -46,7 +46,6 @@ ORKHeadphoneTypeIdentifier const ORKHeadphoneTypeIdentifierAirPodsPro = @"AIRPOD
ORKHeadphoneTypeIdentifier const ORKHeadphoneTypeIdentifierAirPodsProGen2 = @"AIRPODSPROV2";
ORKHeadphoneTypeIdentifier const ORKHeadphoneTypeIdentifierAirPodsMax = @"AIRPODSMAX";
ORKHeadphoneTypeIdentifier const ORKHeadphoneTypeIdentifierEarPods = @"EARPODS";
ORKHeadphoneTypeIdentifier const ORKHeadphoneTypeIdentifierUnknown = @"UNKNOWN";
+1 -1
View File
@@ -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
@@ -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";
+2 -7
View File
@@ -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
+72
View File
@@ -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``

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