Compare commits

...

10 Commits

Author SHA1 Message Date
jessi-apple 8b2cf8889a Merge pull request #1592 from simon-apple/dev/swiftUI-beta-update
Public beta 2 - SwiftUI
2025-01-24 09:46:17 -08:00
Simon Tsai 3f83f6ab4f RK SwiftUI Beta 2 Release (#2534) 2025-01-22 11:18:03 -08:00
Corey 7abce4c982 fix: Use accent color instead of hardcoded blue (#1590) 2024-12-19 15:04:39 -08:00
simon-apple eedd39d0a8 Public beta release - SwiftUI 2024-10-21 14:54:38 -07: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
526 changed files with 17459 additions and 2377 deletions
+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
+74
View File
@@ -1,3 +1,5 @@
![ResearchKit](https://github.com/user-attachments/assets/0384c1a6-ec67-45d3-be68-136a2e4cacff)
ResearchKit Framework
===========
@@ -77,6 +79,78 @@ The height question is presented in the figure below.
|---|---|
| ![height-question](https://github.com/ResearchKit/ResearchKit/assets/29615893/4f425329-83b7-45c3-84f9-58cdbcaf2529) | ![height-question-2](https://github.com/ResearchKit/ResearchKit/assets/29615893/2cc0dc2c-5c2a-4b50-a4be-834363fb64b5) |
### ResearchKit SwiftUI
We are excited to announce the release of a new beta API for surveys in ResearchKit. This API is designed to enhance the flexibility, customization, and cross-platform compatibility of surveys in your ResearchKit apps. Below are the key features and usage details.
New Form APIs offer an easily configurable and flexible UI, with the same look and feel of `ORKFormStep`:
* `ResearchForm`
* Manages the navigation between steps in a survey.
* `ResearchFormStep`
* Represents a step in a survey and lays out the header and questions on one page. Question numbers (e.g. 1 of 3) are automatically added at the top of each question to denote progress in a step.
* `ResearchFormCompletion`
* Represents the context for a survey's completion
* `ResearchFormResult`
* Represents responses for the different kinds of questions.
* `StepHeader`
* A step header containing an image, title, and subtitle.
* `QuestionHeader`
* A question header containing a title and detail.
* `InstructionBodyItem`
* Displays an image and text side by side.
* `questionRequired` (`ViewModifier`)
* Designates a question as required or optional.
#### Survey Question Types:
* `MultipleChoiceQuestion`
* `HeightQuestion`
* `WeightQuestion`
* `SliderQuestion`
* `TextQuestion`
* `DateTimeQuestion`
* `NumericQuestion`
* `ImageChoiceQuestion`
The example below shows how to create a `ResearchForm` to present a text question for the participant to answer, and then save their results.
```swift
import ResearchKitSwiftUI
ResearchForm(
id: "SurveyTask",
steps: {
ResearchFormStep(
title: "Demographics",
subtitle: "Tell us about yourself",
content: {
TextQuestion(
id: "textQuestion",
title: "What is your name?",
prompt: "Enter your name here",
lineLimit: .singleLine,
characterLimit: 0
)
.questionRequired(true)
}
)
},
onResearchFormCompletion: { completion in
switch completion {
case .completed(let results):
save(results)
case .discarded:
cancel()
default:
cancel()
}
}
)
```
#### Install as an embedded framework
Download the project source code and drag in the *ResearchKitSwiftUI* folder. In the dialog that pops up, choose to copy files to destination and create folders. Then hit the finish button. Finally, embed the *ResearchKitSwiftUI* framework in your app by adding it to the "Frameworks, Libraries, and Embedded Content" section for your target.
# Consent <a name="consent"></a>
The *ResearchKit framework* provides classes that you can customize to explain the
+32
View File
@@ -1,5 +1,37 @@
# ResearchKit Release Notes
## 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
+3
View File
@@ -7,4 +7,7 @@
<FileRef
location = "group:samples/ORKCatalog/ORKCatalog.xcodeproj">
</FileRef>
<FileRef
location = "group:ResearchKitSwiftUI/ResearchKitSwiftUI.xcodeproj">
</FileRef>
</Workspace>
+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>
@@ -54,6 +54,36 @@
<Test
Identifier = "ORKDataCollectionTests">
</Test>
<Test
Identifier = "ORKJSONSerializationTests">
</Test>
<Test
Identifier = "ORKJSONSerializationTests/testAddResult">
</Test>
<Test
Identifier = "ORKJSONSerializationTests/testDateComponentsSerialization">
</Test>
<Test
Identifier = "ORKJSONSerializationTests/testEquality">
</Test>
<Test
Identifier = "ORKJSONSerializationTests/testInvalidDBHLValue">
</Test>
<Test
Identifier = "ORKJSONSerializationTests/testMissingDefaultValueKeyInScaleAnswerFormat">
</Test>
<Test
Identifier = "ORKJSONSerializationTests/testORKSampleDeserialization">
</Test>
<Test
Identifier = "ORKJSONSerializationTests/testORKSerialization">
</Test>
<Test
Identifier = "ORKJSONSerializationTests/testSecureCoding">
</Test>
<Test
Identifier = "ORKJSONSerializationTests/testTaskModel">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
@@ -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>
+5 -1
View File
@@ -14,7 +14,11 @@
"testTargets" : [
{
"skippedTests" : [
"ORKDataCollectionTests"
"ORKDataCollectionTests",
"ORKJSONSerializationTests\/testEquality",
"ORKJSONSerializationTests\/testORKSampleDeserialization",
"ORKJSONSerializationTests\/testORKSerialization",
"ORKJSONSerializationTests\/testSecureCoding"
],
"target" : {
"containerPath" : "container:ResearchKit.xcodeproj",
@@ -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 -10
View File
@@ -32,11 +32,7 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <UIKit/UIKit.h>
#if TARGET_OS_IOS
#import <ResearchKit/ORKTypes.h>
@class ORKScaleAnswerFormat;
@@ -56,11 +52,12 @@
@class ORKLocationAnswerFormat;
@class ORKSESAnswerFormat;
@class ORKImageChoice;
#endif
NS_ASSUME_NONNULL_BEGIN
@class ORKBooleanAnswerFormat;
@class ORKColorChoiceAnswerFormat;
@class ORKColorChoice;
@class ORKTextChoiceAnswerFormat;
@class ORKTextChoice;
@@ -123,6 +120,8 @@ ORK_CLASS_AVAILABLE
+ (ORKTextChoiceAnswerFormat *)choiceAnswerFormatWithStyle:(ORKChoiceAnswerStyle)style
textChoices:(NSArray<ORKTextChoice *> *)textChoices;
+ (ORKColorChoiceAnswerFormat *)choiceAnswerFormatWithStyle:(ORKChoiceAnswerStyle)style
colorChoices:(NSArray<ORKColorChoice *> *)colorChoices;
/// @name Validation
@@ -189,9 +188,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,11 +405,35 @@ ORK_CLASS_AVAILABLE
@end
ORK_CLASS_AVAILABLE
@interface ORKColorChoice: NSObject <NSSecureCoding, NSCopying, NSObject>
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
#pragma mark - iOS
- (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
#if TARGET_OS_IOS
@interface ORKAnswerFormat()
/// @name Factory methods
@@ -480,8 +523,9 @@ ORK_CLASS_AVAILABLE
minimumValue:(double)minimumValue
maximumValue:(double)maximumValue
defaultValue:(double)defaultValue;
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION && TARGET_OS_IOS
+ (ORKLocationAnswerFormat *)locationAnswerFormat;
#endif
+ (ORKSESAnswerFormat *)socioEconomicAnswerFormatWithTopRungText:(NSString *)topRungText bottomRungText:(NSString *)bottomRungText;
@@ -1737,6 +1781,7 @@ This By default, the value of this property is `NO`.
*/
@property (copy, nullable) NSString *placeholder;
#if !TARGET_OS_WATCH
/**
The autocapitalization type that applies to the user's input.
@@ -1779,6 +1824,7 @@ This By default, the value of this property is `NO`.
If specified, overrides the default password generation rules for fields with secureTextEntry.
*/
@property (nonatomic, copy, nullable) UITextInputPasswordRules *passwordRules API_AVAILABLE(ios(12));
#endif
@end
@@ -2026,6 +2072,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 +2207,7 @@ ORK_CLASS_AVAILABLE
An `ORKLocationAnswerFormat` object produces an `ORKLocationQuestionResult` object.
*/
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION && TARGET_OS_IOS
ORK_CLASS_AVAILABLE
@interface ORKLocationAnswerFormat : ORKAnswerFormat
@@ -2051,6 +2226,7 @@ ORK_CLASS_AVAILABLE
@property (copy, nullable) NSString *placeholder;
@end
#endif
/**
Socio-Economic Ladder Answer Format.
@@ -2067,6 +2243,4 @@ ORK_CLASS_AVAILABLE
@end
#endif
NS_ASSUME_NONNULL_END
+459 -26
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,20 +83,23 @@ NSString *ORKQuestionTypeString(ORKQuestionType questionType) {
SQT_CASE(Weight);
SQT_CASE(Location);
SQT_CASE(SES);
SQT_CASE(Age);
SQT_CASE(Year);
}
#undef SQT_CASE
}
#if TARGET_OS_IOS
static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattingStyle style) {
return style == ORKNumberFormattingStylePercent ? NSNumberFormatterPercentStyle : NSNumberFormatterDecimalStyle;
}
#if TARGET_OS_IOS
@implementation ORKAnswerDefaultSource {
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,17 +279,16 @@ static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattin
[answerFormat setHealthKitUserUnit:healthKitDefault];
}
}
#endif // ORK_FEATURE_HEALTHKIT_AUTHORIZATION
@end
#endif
#endif // TARGET_OS_IOS
#pragma mark - ORKAnswerFormat
@implementation ORKAnswerFormat
#if TARGET_OS_IOS
+ (ORKScaleAnswerFormat *)scaleAnswerFormatWithMaximumValue:(NSInteger)scaleMaximum
minimumValue:(NSInteger)scaleMinimum
defaultValue:(NSInteger)defaultValue
@@ -412,7 +422,7 @@ static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattin
calendar:calendar];
[answerFormat setDaysBeforeCurrentDateToSetMinimumDate:daysBefore];
[answerFormat setDaysAfterCurrentDateToSetMinimumDate:daysAfter];
return answerFormat;
}
@@ -477,9 +487,11 @@ static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattin
defaultValue:defaultValue];
}
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION && TARGET_OS_IOS
+ (ORKLocationAnswerFormat *)locationAnswerFormat {
return [ORKLocationAnswerFormat new];
}
#endif
+ (ORKSESAnswerFormat *)socioEconomicAnswerFormatWithTopRungText:(NSString *)topRungText
bottomRungText:(NSString *)bottomRungText {
@@ -487,8 +499,6 @@ static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattin
bottomRungText:bottomRungText];
}
#endif
+ (ORKBooleanAnswerFormat *)booleanAnswerFormat {
return [ORKBooleanAnswerFormat new];
}
@@ -502,6 +512,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 +571,7 @@ static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattin
return NO;
}
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
- (HKObjectType *)healthKitObjectType {
return nil;
}
@@ -576,6 +591,7 @@ static NSNumberFormatterStyle ORKNumberFormattingStyleConvert(ORKNumberFormattin
- (void)setHealthKitUserUnit:(HKUnit *)unit {
}
#endif
- (ORKQuestionType)questionType {
return ORKQuestionTypeNone;
@@ -668,7 +684,6 @@ static NSArray *ork_processTextChoices(NSArray<ORKTextChoice *> *textChoices) {
return choices;
}
#if TARGET_OS_IOS
@implementation ORKValuePickerAnswerFormat {
ORKChoiceAnswerFormatHelper *_helper;
ORKTextChoice *_nullTextChoice;
@@ -821,7 +836,7 @@ static NSArray *ork_processTextChoices(NSArray<ORKTextChoice *> *textChoices) {
- (BOOL)isEqual:(id)object {
BOOL isParentSame = [super isEqual:object];
__typeof(self) castObject = object;
return (isParentSame &&
ORKEqualObjects(self.valuePickers, castObject.valuePickers));
@@ -870,7 +885,7 @@ static NSArray *ork_processTextChoices(NSArray<ORKTextChoice *> *textChoices) {
if (![answer isKindOfClass:[NSArray class]] || ([(NSArray*)answer count] != self.valuePickers.count)) {
return nil;
}
NSArray *answers = (NSArray*)answer;
__block NSMutableArray <NSString *> *answerTexts = [NSMutableArray new];
[answers enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
@@ -881,11 +896,11 @@ static NSArray *ork_processTextChoices(NSArray<ORKTextChoice *> *textChoices) {
*stop = YES;
}
}];
if (answerTexts.count != self.valuePickers.count) {
return nil;
}
return [answerTexts componentsJoinedByString:self.separator];
}
@@ -1007,8 +1022,6 @@ static NSArray *ork_processTextChoices(NSArray<ORKTextChoice *> *textChoices) {
}
@end
#endif
#pragma mark - ORKTextChoiceAnswerFormat
@@ -1106,9 +1119,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,10 +1391,96 @@ 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
#if TARGET_OS_IOS
@implementation ORKTextChoiceOther
+ (instancetype)new {
@@ -1497,7 +1704,6 @@ NSArray<Class> *ORKAllowableValueClasses(void) {
}
@end
#endif
#pragma mark - ORKBooleanAnswerFormat
@@ -1585,7 +1791,7 @@ NSArray<Class> *ORKAllowableValueClasses(void) {
#pragma mark - ORKTimeOfDayAnswerFormat
#if TARGET_OS_IOS
@implementation ORKTimeOfDayAnswerFormat
- (instancetype)init {
@@ -2612,7 +2818,7 @@ NSArray<Class> *ORKAllowableValueClasses(void) {
#pragma mark - ORKTextScaleAnswerFormat
#if TARGET_OS_IOS
@interface ORKTextScaleAnswerFormat () {
ORKChoiceAnswerFormatHelper *_helper;
@@ -2823,19 +3029,15 @@ NSArray<Class> *ORKAllowableValueClasses(void) {
@end
#endif
#pragma mark - ORKTextAnswerFormat
@interface ORKTextAnswerFormat()
@end
@implementation ORKTextAnswerFormat
- (Class)questionResultClass {
return [ORKTextQuestionResult class];
}
@@ -2854,7 +3056,6 @@ NSArray<Class> *ORKAllowableValueClasses(void) {
}
- (instancetype)initWithMaximumLength:(NSInteger)maximumLength {
self = [super init];
if (self) {
@@ -2916,6 +3117,7 @@ NSArray<Class> *ORKAllowableValueClasses(void) {
answerFormat->_spellCheckingType = _spellCheckingType;
answerFormat->_keyboardType = _keyboardType;
answerFormat->_textContentType = _textContentType;
if (@available(iOS 12.0, *)) {
answerFormat->_passwordRules = _passwordRules;
}
@@ -2992,6 +3194,7 @@ NSArray<Class> *ORKAllowableValueClasses(void) {
answerFormat->_keyboardType = _keyboardType;
answerFormat->_autocapitalizationType = _autocapitalizationType;
answerFormat->_textContentType = _textContentType;
if (@available(iOS 12.0, *)) {
answerFormat->_passwordRules = _passwordRules;
}
@@ -3104,7 +3307,6 @@ static NSString *const kSecureTextEntryEscapeString = @"*";
return answerString;
}
- (ORKQuestionResult *)resultWithIdentifier:(NSString *)identifier answer:(id)answer {
ORKQuestionResult *questionResult = nil;
questionResult = (ORKQuestionResult *)[super resultWithIdentifier:identifier answer:answer];
@@ -3572,6 +3774,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 && TARGET_OS_IOS
#pragma mark - ORKLocationAnswerFormat
@implementation ORKLocationAnswerFormat
@@ -3642,6 +4075,7 @@ static NSString *const kSecureTextEntryEscapeString = @"*";
}
@end
#endif
#pragma mark ORKSESAnswerFormat
@@ -3704,4 +4138,3 @@ static NSString *const kSecureTextEntryEscapeString = @"*";
}
@end
#endif
+23 -15
View File
@@ -29,11 +29,13 @@
*/
@import HealthKit;
#if TARGET_OS_IOS
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
#import <HealthKit/HealthKit.h>
#endif
#import <ResearchKit/ORKAnswerFormat_Private.h>
#import <ResearchKit/ORKChoiceAnswerFormatHelper.h>
#endif
@class ORKChoiceAnswerFormatHelper;
NS_ASSUME_NONNULL_BEGIN
@@ -41,9 +43,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.
@@ -53,7 +57,7 @@ NSString *ORKQuestionTypeString(ORKQuestionType questionType);
@end
ORK_DESIGNATE_CODING_AND_SERIALIZATION_INITIALIZERS(ORKAnswerFormat)
#if TARGET_OS_IOS
#if TARGET_OS_IOS || TARGET_OS_VISION
ORK_DESIGNATE_CODING_AND_SERIALIZATION_INITIALIZERS(ORKImageChoiceAnswerFormat)
ORK_DESIGNATE_CODING_AND_SERIALIZATION_INITIALIZERS(ORKValuePickerAnswerFormat)
ORK_DESIGNATE_CODING_AND_SERIALIZATION_INITIALIZERS(ORKMultipleValuePickerAnswerFormat)
@@ -69,6 +73,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 +88,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;
@@ -127,6 +134,11 @@ ORK_DESIGNATE_CODING_AND_SERIALIZATION_INITIALIZERS(ORKTextChoice)
@end
@interface ORKDateAnswerFormat () {
NSDate *_currentDateOverride;
}
@end
#if TARGET_OS_IOS
@protocol ORKScaleAnswerFormatProvider <NSObject>
@@ -190,6 +202,7 @@ NSArray<Class> *ORKAllowableValueClasses(void);
@end
#if TARGET_OS_IOS
@interface ORKValuePickerAnswerFormat ()
- (instancetype)initWithTextChoices:(NSArray<ORKTextChoice *> *)textChoices nullChoice:(ORKTextChoice *)nullChoice NS_DESIGNATED_INITIALIZER;
@@ -198,7 +211,6 @@ NSArray<Class> *ORKAllowableValueClasses(void);
@end
@interface ORKImageChoice () <ORKAnswerOption>
@end
@@ -210,11 +222,7 @@ NSArray<Class> *ORKAllowableValueClasses(void);
@end
@interface ORKDateAnswerFormat () {
NSDate *_currentDateOverride;
}
@interface ORKDateAnswerFormat ()
- (NSDate *)pickerDefaultDate;
- (nullable NSDate *)pickerMinimumDate;
- (nullable NSDate *)pickerMaximumDate;
@@ -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()
@@ -28,12 +28,7 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if TARGET_OS_IOS
#import <ResearchKit/ORKAnswerFormat.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@@ -60,7 +55,6 @@ ORK_EXTERN id ORKNullAnswerValue(void) ORK_AVAILABLE_DECL;
An `ORKConfirmTextAnswerFormat` object produces an `ORKBooleanQuestionResult` object.
*/
#if TARGET_OS_IOS
ORK_CLASS_AVAILABLE
@interface ORKConfirmTextAnswerFormat : ORKTextAnswerFormat
@@ -95,7 +89,6 @@ ORK_CLASS_AVAILABLE
@property (nonatomic, copy, readonly) NSString *errorMessage;
@end
#endif
@protocol ORKAnswerFormatPlatterPresentable <NSObject>
+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
+14 -2
View File
@@ -30,16 +30,20 @@
#import "ORKBodyItem.h"
#import "ORKBodyItem_Internal.h"
#import "ORKLearnMoreInstructionStep.h"
#import "ORKHelpers_Internal.h"
#if !TARGET_OS_WATCH
#import "ORKBodyItem_Internal.h"
#endif
@implementation ORKBodyItem
{
// For our internal custom button type
BOOL _isCustomButtonType;
}
#if !TARGET_OS_WATCH
- (instancetype)initWithCustomButtonConfigurationHandler:(void(^)(UIButton *button))configurationHandler
{
self = [super init];
@@ -50,6 +54,7 @@
}
return self;
}
#endif
- (BOOL)isCustomButtonItemType
{
@@ -61,6 +66,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 +79,7 @@
self.image = image;
self.useCardStyle = useCardStyle;
self.useSecondaryColor = NO;
self.alignImageToTop = alignImageToTop;
}
[self validateParameters];
return self;
@@ -127,6 +137,7 @@
bodyItem->_image = [self.image copy];
bodyItem->_useCardStyle = self.useCardStyle;
bodyItem->_useSecondaryColor = self.useSecondaryColor;
bodyItem->_alignImageToTop = self.alignImageToTop;
return bodyItem;
}
@@ -146,7 +157,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
@@ -34,9 +34,11 @@ NS_ASSUME_NONNULL_BEGIN
@interface ORKBodyItem ()
#if !TARGET_OS_WATCH
@property (nonatomic, copy, nullable) void (^customButtonConfigurationHandler)(UIButton *button);
- (instancetype)initWithCustomButtonConfigurationHandler:(void(^)(UIButton *button))configurationHandler;
#endif
- (BOOL)isCustomButtonItemType;
@@ -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];
-3
View File
@@ -28,10 +28,7 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if TARGET_OS_IOS
#import <ResearchKit/ORKResult.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@@ -29,11 +29,7 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if TARGET_OS_IOS
#import <ResearchKit/ORKCollectionResult.h>
#endif
NS_ASSUME_NONNULL_BEGIN
+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()
+1 -2
View File
@@ -30,10 +30,9 @@
#import <Foundation/Foundation.h>
#import <ResearchKit/ORKInstructionStep.h>
#if TARGET_OS_IOS
#import <ResearchKit/ORKInstructionStep.h>
#import <ResearchKit/ORKTask.h>
#endif
@@ -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
@@ -28,6 +28,7 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !TARGET_OS_VISION
#import <Foundation/Foundation.h>
#import <ResearchKit/ResearchKit.h>
@@ -60,6 +61,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 +75,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 +147,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 +169,7 @@ ORK_CLASS_AVAILABLE
units:(NSArray<HKUnit *> *)units
startDate:(NSDate *)startDate
error:(NSError * _Nullable *)error;
#endif
/**
Add a collector for motion activity.
@@ -198,3 +201,5 @@ ORK_CLASS_AVAILABLE
@end
NS_ASSUME_NONNULL_END
#endif
+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)
-3
View File
@@ -29,10 +29,7 @@
*/
#import <Foundation/Foundation.h>
#if TARGET_OS_IOS
#import <ResearchKit/ORKDefines.h>
#endif
NS_ASSUME_NONNULL_BEGIN
-3
View File
@@ -28,10 +28,7 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if TARGET_OS_IOS
#import <ResearchKit/ORKDevice.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@@ -29,11 +29,7 @@
*/
#import <Foundation/Foundation.h>
#if TARGET_OS_IOS
#import <ResearchKit/ORKDefines.h>
#endif
NS_ASSUME_NONNULL_BEGIN
+1 -6
View File
@@ -29,13 +29,8 @@
*/
@import Foundation;
#if TARGET_OS_IOS
#import <Foundation/Foundation.h>
#import <ResearchKit/ORKDefines.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@@ -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
+10 -5
View File
@@ -30,12 +30,8 @@
#import <Foundation/Foundation.h>
#if TARGET_OS_IOS
#import <ResearchKit/ORKStep.h>
#import <ResearchKit/ORKDefines.h>
#endif
#import <ResearchKit/ORKStep.h>
/**
Values that determine the style
@@ -111,6 +107,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 +172,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.
+22 -1
View File
@@ -39,7 +39,10 @@
#import "ORKStep_Private.h"
#import "ORKHelpers_Internal.h"
#if !TARGET_OS_WATCH
#import "ORKFormItemVisibilityRule.h"
#endif
@implementation ORKFormStep
@@ -53,6 +56,7 @@
self.optional = YES;
self.useSurveyMode = YES;
self.useCardView = YES;
self.autoScrollEnabled = YES;
self.cardViewStyle = ORKCardViewStyleDefault;
}
return self;
@@ -64,6 +68,7 @@
self.optional = YES;
self.useSurveyMode = YES;
self.useCardView = YES;
self.autoScrollEnabled = YES;
self.cardViewStyle = ORKCardViewStyleDefault;
}
return self;
@@ -93,6 +98,7 @@
ORKFormStep *step = [super copyWithZone:zone];
step.formItems = ORKArrayCopyObjects(_formItems);
step.cardViewStyle = self.cardViewStyle;
step.autoScrollEnabled = self.autoScrollEnabled;
return step;
}
@@ -102,7 +108,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 +152,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 +163,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 +185,7 @@
}
}
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION && TARGET_OS_IOS
- (NSSet<HKObjectType *> *)requestedHealthKitTypesForReading {
NSMutableSet<HKObjectType *> *healthTypes = [NSMutableSet set];
@@ -189,6 +199,7 @@
return healthTypes.count ? healthTypes : nil;
}
#endif
@end
@@ -254,6 +265,7 @@
return self;
}
#if TARGET_OS_IOS
- (ORKFormItem *)confirmationAnswerFormItemWithIdentifier:(NSString *)identifier
text:(nullable NSString *)text
errorMessage:(NSString *)errorMessage {
@@ -273,6 +285,7 @@
optional:self.optional];
return item;
}
#endif
+ (BOOL)supportsSecureCoding {
return YES;
@@ -286,7 +299,9 @@
item->_learnMoreItem = [_learnMoreItem copy];
item->_showsProgress = _showsProgress;
item->_tagText = [_tagText copy];
#if !TARGET_OS_WATCH
item->_visibilityRule = [_visibilityRule copy];
#endif
return item;
}
@@ -303,7 +318,9 @@
ORK_DECODE_OBJ_CLASS(aDecoder, answerFormat, ORKAnswerFormat);
ORK_DECODE_OBJ_CLASS(aDecoder, step, ORKFormStep);
ORK_DECODE_OBJ_CLASS(aDecoder, tagText, NSString);
#if !TARGET_OS_WATCH
ORK_DECODE_OBJ_CLASS(aDecoder, visibilityRule, ORKFormItemVisibilityRule);
#endif
}
return self;
}
@@ -342,8 +359,12 @@
}
- (NSUInteger)hash {
#if !TARGET_OS_WATCH
// Ignore the step reference - it's not part of the content of this item
return _identifier.hash ^ _text.hash ^ _placeholder.hash ^ _answerFormat.hash ^ (_optional ? 0xf : 0x0) ^ _detailText.hash ^ _learnMoreItem.hash ^ (_showsProgress ? 0xf : 0x0) ^ _tagText.hash ^ _visibilityRule.hash;
#else
return _identifier.hash ^ _text.hash ^ _placeholder.hash ^ _answerFormat.hash ^ (_optional ? 0xf : 0x0) ^ _detailText.hash ^ _learnMoreItem.hash ^ (_showsProgress ? 0xf : 0x0) ^ _tagText.hash;
#endif
}
- (ORKAnswerFormat *)impliedAnswerFormat {
+8 -2
View File
@@ -29,9 +29,12 @@
*/
#import <HealthKit/HealthKit.h>
#import <ResearchKit/ORKAnswerFormat.h>
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION && TARGET_OS_IOS
#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 && TARGET_OS_IOS
ORK_CLASS_AVAILABLE
@interface ORKHealthKitCharacteristicTypeAnswerFormat : ORKAnswerFormat
@@ -222,5 +227,6 @@ included in the question result generated by form items or question steps
@end
NS_ASSUME_NONNULL_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;
}
+12 -10
View File
@@ -29,19 +29,13 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@import UIKit;
#if TARGET_OS_IOS
#import <ResearchKit/ORKTypes.h>
#import <ResearchKit/ORKHelpers_Private.h>
#import <ResearchKit/ORKErrors.h>
#endif
#import <Foundation/Foundation.h>
#import <os/log.h>
#import <UIKit/UIKit.h>
#import <ResearchKit/ORKErrors.h>
#import <ResearchKit/ORKHelpers_Private.h>
#import <ResearchKit/ORKTypes.h>
NS_ASSUME_NONNULL_BEGIN
@@ -211,6 +205,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 +366,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 -5
View File
@@ -29,12 +29,8 @@
*/
@import Foundation;
#if TARGET_OS_IOS
#import <Foundation/Foundation.h>
#import <ResearchKit/ORKDefines.h>
#endif
NS_ASSUME_NONNULL_BEGIN
-6
View File
@@ -28,14 +28,8 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <UIKit/UIKit.h>
#if TARGET_OS_IOS
#import <ResearchKit/ORKStep.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@@ -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
-5
View File
@@ -30,12 +30,7 @@
#import <UIKit/UIKit.h>
#if TARGET_OS_IOS
#import <ResearchKit/ORKTask.h>
#endif
NS_ASSUME_NONNULL_BEGIN
+10 -16
View File
@@ -30,16 +30,19 @@
*/
#import "ORKOrderedTask.h"
#import "ORKAnswerFormat.h"
#import "ORKInstructionStep.h"
#import "ORKCompletionStep.h"
#import "ORKStep_Private.h"
#import "ORKHelpers_Internal.h"
#import "ORKSkin.h"
#if TARGET_OS_IOS
#import "ORKQuestionStep.h"
#import "ORKFormStep.h"
#import "ORKFormItem_Internal.h"
#import "ORKHelpers_Internal.h"
#import "ORKInstructionStep.h"
#import "ORKQuestionStep.h"
#import "ORKSkin.h"
#import "ORKStep_Private.h"
#if TARGET_OS_IOS
#import "ORKActiveStep_Internal.h"
#import "ORKEarlyTerminationConfiguration.h"
#endif
@@ -263,7 +266,6 @@
int currentStepStartingProgressNumber = 0;
for (ORKStep *step in self.steps) {
#if TARGET_OS_IOS
if ([step isKindOfClass:[ORKFormStep class]]) {
ORKFormStep *formStep = (ORKFormStep *)step;
if (formStep.identifier == currentStep.identifier) {
@@ -277,14 +279,6 @@
}
totalQuestions += 1;
}
#else
if ([step isKindOfClass:[ORKQuestionStep class]]) {
if (step.identifier == currentStep.identifier) {
currentStepStartingProgressNumber = (totalQuestions + 1);
}
totalQuestions += 1;
}
#endif
}
totalProgress.currentStepStartingProgressPosition = currentStepStartingProgressNumber;
@@ -293,7 +287,6 @@
return totalProgress;
}
#if TARGET_OS_IOS
- (NSMutableArray *)calculateSectionsForFormItems:(NSArray *)formItems {
NSMutableArray<NSMutableArray *> *_sections = [NSMutableArray new];
NSMutableArray *section = nil;
@@ -374,6 +367,7 @@
return NO;
}
#if TARGET_OS_IOS
- (BOOL)providesBackgroundAudioPrompts {
BOOL providesAudioPrompts = NO;
for (ORKStep *step in self.steps) {
-4
View File
@@ -28,12 +28,8 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if TARGET_OS_IOS
#import <ResearchKit/ORKStep.h>
#import <ResearchKit/ORKOrderedTask.h>
#endif
NS_ASSUME_NONNULL_BEGIN
+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 -1
View File
@@ -32,6 +32,7 @@
#import <UIKit/UIKit.h>
#import <ResearchKit/ORKDefines.h>
#import <UserNotifications/UserNotifications.h>
NS_ASSUME_NONNULL_BEGIN
@@ -49,7 +50,6 @@ typedef NS_ENUM(NSInteger, ORKRequestPermissionsState) {
ORKRequestPermissionsStateError,
};
typedef NS_OPTIONS(NSUInteger, UNAuthorizationOptions);
typedef NSString * SRSensor NS_TYPED_ENUM API_AVAILABLE(ios(14.0));
/**
@@ -79,7 +79,9 @@ ORK_CLASS_AVAILABLE
+ (ORKMotionActivityPermissionType *) deviceMotionPermissionType;
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
+ (ORKLocationPermissionType *) locationPermissionType;
#endif
@end
+2
View File
@@ -83,9 +83,11 @@
return [[ORKMotionActivityPermissionType alloc] init];
}
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
+ (ORKLocationPermissionType *) locationPermissionType {
return [[ORKLocationPermissionType alloc] init];
}
#endif
@end
+11 -9
View File
@@ -28,13 +28,12 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if TARGET_OS_IOS
#import <ResearchKit/ORKResult.h>
#endif
#import <CoreLocation/CLLocation.h>
#import <Contacts/Contacts.h>
#import <ResearchKit/ORKResult.h>
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION && TARGET_OS_IOS
#import <CoreLocation/CLLocation.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@@ -150,8 +149,9 @@ ORK_CLASS_AVAILABLE
@end
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION && TARGET_OS_IOS
/**
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 +180,7 @@ ORK_CLASS_AVAILABLE
@property (nonatomic, copy, readonly, nullable) CNPostalAddress *postalAddress;
@end
#endif
/**
A result object from a location answer format.
@@ -192,6 +192,8 @@ 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 && TARGET_OS_IOS
ORK_CLASS_AVAILABLE
@interface ORKLocationQuestionResult : ORKQuestionResult
@@ -201,7 +203,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.
+13 -10
View File
@@ -28,15 +28,18 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <ResearchKit/ORKAnswerFormat_Internal.h>
#import <ResearchKit/ORKAnswerFormat_Private.h>
#import <ResearchKit/ORKHelpers_Internal.h>
#import <ResearchKit/ORKQuestionResult.h>
#import <ResearchKit/ORKQuestionStep.h>
#import <ResearchKit/ORKQuestionStep_Private.h>
#import <ResearchKit/ORKResult_Private.h>
#import <ResearchKit/ORKStep_Private.h>
#import "ORKQuestionResult_Private.h"
#import "ORKResult_Private.h"
#if TARGET_OS_IOS
#import "ORKQuestionStep.h"
#import "ORKHelpers_Internal.h"
#import "ORKAnswerFormat_Internal.h"
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION && TARGET_OS_IOS
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#endif
@implementation ORKQuestionResult {
@@ -326,7 +329,7 @@
@end
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION && TARGET_OS_IOS
#pragma mark - ORKLocationQuestionResult
@implementation ORKLocation
@@ -468,7 +471,7 @@ static NSString *const RegionIdentifierKey = @"region.identifier";
}
@end
#endif
#pragma mark - ORKSESQuestionResult
@@ -28,14 +28,9 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if TARGET_OS_IOS
#import <ResearchKit/ORKQuestionResult.h>
#endif
@import MapKit;
#import <MapKit/MapKit.h>
NS_ASSUME_NONNULL_BEGIN
@@ -49,9 +44,10 @@ NS_ASSUME_NONNULL_BEGIN
@end
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION && TARGET_OS_IOS
@interface ORKLocation ()
- (instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate
region:(nullable CLCircularRegion *)region
userInput:(nullable NSString *)userInput
@@ -60,5 +56,6 @@ 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
-4
View File
@@ -29,11 +29,7 @@
*/
#import <Foundation/Foundation.h>
#if TARGET_OS_IOS
#import <ResearchKit/ORKTypes.h>
#endif
NS_ASSUME_NONNULL_BEGIN
+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
-3
View File
@@ -28,10 +28,7 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if TARGET_OS_IOS
#import <ResearchKit/ORKResult.h>
#endif
NS_ASSUME_NONNULL_BEGIN
-4
View File
@@ -28,12 +28,8 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <UIKit/UIKit.h>
#if TARGET_OS_IOS
#import <ResearchKit/ORKDefines.h>
#endif
NS_ASSUME_NONNULL_BEGIN
+1 -5
View File
@@ -29,12 +29,8 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@import UIKit;
#if TARGET_OS_IOS
#import <UIKit/UIKit.h>
#import <ResearchKit/ORKSkin.h>
#endif
#if TARGET_OS_IOS
+15 -16
View File
@@ -28,13 +28,9 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if TARGET_OS_IOS
#import <ResearchKit/ORKTypes.h>
#endif
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <ResearchKit/ORKTypes.h>
@class HKObjectType;
@class ORKResult;
@@ -51,19 +47,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 +176,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 +236,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
@@ -252,7 +248,7 @@ ORK_CLASS_AVAILABLE API_AVAILABLE(ios(11.0), watchos(6.0))
#pragma mark - iOS
#if TARGET_OS_IOS
#if TARGET_OS_IOS || TARGET_OS_VISION
@class ORKBodyItem;
@@ -272,7 +268,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 +299,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.
*/
@@ -313,4 +309,7 @@ API_AVAILABLE(ios(11))
#endif
#pragma mark - watchOS / VisionOS
NS_ASSUME_NONNULL_END
-3
View File
@@ -28,10 +28,7 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if TARGET_OS_IOS
#import <ResearchKit/ORKStep.h>
#endif
NS_ASSUME_NONNULL_BEGIN
+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 -5
View File
@@ -30,13 +30,12 @@
#import <Foundation/Foundation.h>
#if ORK_FEATURE_HEALTHKIT_AUTHORIZATION
#import <HealthKit/HealthKit.h>
#if TARGET_OS_IOS
#import <ResearchKit/ORKTypes.h>
#endif
#import <ResearchKit/ORKTypes.h>
NS_ASSUME_NONNULL_BEGIN
@@ -271,6 +270,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 +283,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 -5
View File
@@ -30,11 +30,7 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#if TARGET_OS_IOS
#import <ResearchKit/ORKDefines.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@@ -131,6 +127,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 +396,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>
+2
View File
@@ -87,12 +87,14 @@ ORK_CLASS_AVAILABLE
*/
@property (nonatomic, getter=isAudioMute) BOOL audioMute;
#if !TARGET_OS_VISION
/**
Constants indicating the desired torch mode to use
The default value is `AVCaptureTorchModeAuto` (see `AVCaptureTorchMode`).
*/
@property (nonatomic) AVCaptureTorchMode torchMode;
#endif
/**
Constants indicating the physical position of an AVCaptureDevice's hardware on the system.
+2
View File
@@ -63,8 +63,10 @@ NS_ASSUME_NONNULL_BEGIN
@optional
- (UIView<ORKCustomSignatureAccessoryViewProtocol> * _Nullable)customHeaderViewForSignatureContent;
#if !TARGET_OS_VISION
@optional
- (UIScrollViewKeyboardDismissMode)keyboardDismissModeForCustomView;
#endif
@end
@@ -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
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

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