2863 lines
163 KiB
Objective-C
2863 lines
163 KiB
Objective-C
/*
|
|
Copyright (c) 2015, Apple Inc. All rights reserved.
|
|
Copyright (c) 2015-2016, Ricardo Sánchez-Sáez.
|
|
Copyright (c) 2018, Brian Ganninger.
|
|
|
|
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 "ORKESerialization.h"
|
|
|
|
#import <ResearchKit/ResearchKit.h>
|
|
#import <ResearchKit/ResearchKit_Private.h>
|
|
#import <ResearchKitActiveTask/ResearchKitActiveTask.h>
|
|
#import <ResearchKitActiveTask/ResearchKitActiveTask_Private.h>
|
|
|
|
|
|
#import <MapKit/MapKit.h>
|
|
#import <Speech/Speech.h>
|
|
|
|
ORKESerializationKey const ORKESerializationKeyImageName = @"imageName";
|
|
|
|
static NSString *_ClassKey = @"_class";
|
|
|
|
static NSString *ORKEStringFromDateISO8601(NSDate *date) {
|
|
static NSDateFormatter *formatter = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
formatter = [[NSDateFormatter alloc] init];
|
|
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
|
|
[formatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
|
|
});
|
|
return [formatter stringFromDate:date];
|
|
}
|
|
|
|
static NSDate *ORKEDateFromStringISO8601(NSString *string) {
|
|
static NSDateFormatter *formatter = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
formatter = [[NSDateFormatter alloc] init];
|
|
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
|
|
[formatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
|
|
});
|
|
return [formatter dateFromString:string];
|
|
}
|
|
|
|
static NSArray *ORKNumericAnswerStyleTable(void) {
|
|
static NSArray *table = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
table = @[@"decimal", @"integer"];
|
|
});
|
|
return table;
|
|
}
|
|
|
|
static NSArray *ORKImageChoiceAnswerStyleTable(void) {
|
|
static NSArray *table = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
table = @[@"singleChoice", @"multipleChoice"];
|
|
});
|
|
return table;
|
|
}
|
|
|
|
static NSArray *ORKMeasurementSystemTable(void) {
|
|
static NSArray *table = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
table = @[@"local", @"metric", @"USC"];
|
|
});
|
|
return table;
|
|
}
|
|
|
|
static id tableMapForward(NSInteger index, NSArray *table) {
|
|
return table[(NSUInteger)index];
|
|
}
|
|
|
|
static NSInteger tableMapReverse(id value, NSArray *table) {
|
|
NSUInteger idx = [table indexOfObject:value];
|
|
if (idx == NSNotFound)
|
|
{
|
|
idx = 0;
|
|
}
|
|
return (NSInteger)idx;
|
|
}
|
|
|
|
static NSDictionary *dictionaryFromCGPoint(CGPoint p) {
|
|
return @{ @"x": @(p.x), @"y": @(p.y) };
|
|
}
|
|
|
|
static NSDictionary *dictionaryFromNSRange(NSRange r) {
|
|
return @{ @"location": @(r.location) , @"length": @(r.length) };
|
|
}
|
|
|
|
API_AVAILABLE(ios(13.0))
|
|
static NSDictionary *dictionaryFromSFAcousticFeature(SFAcousticFeature *acousticFeature) {
|
|
if (acousticFeature == nil) { return @{}; }
|
|
return @{ @"acousticFeatureValuePerFrame" : acousticFeature.acousticFeatureValuePerFrame,
|
|
@"frameDuration" : @(acousticFeature.frameDuration)
|
|
};
|
|
}
|
|
|
|
API_AVAILABLE(ios(13.0))
|
|
static NSDictionary *dictionaryFromSFVoiceAnalytics(SFVoiceAnalytics *voiceAnalytics) {
|
|
if (voiceAnalytics == nil) { return @{}; }
|
|
return @{
|
|
@"jitter" : dictionaryFromSFAcousticFeature(voiceAnalytics.jitter),
|
|
@"shimmer" : dictionaryFromSFAcousticFeature(voiceAnalytics.shimmer),
|
|
@"pitch" : dictionaryFromSFAcousticFeature(voiceAnalytics.pitch),
|
|
@"voicing" : dictionaryFromSFAcousticFeature(voiceAnalytics.voicing)
|
|
};
|
|
}
|
|
|
|
static NSDictionary *dictionaryFromSFTranscriptionSegment(SFTranscriptionSegment *segment) {
|
|
if (segment == nil) { return @{}; }
|
|
|
|
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
|
|
|
[dict setObject:segment.substring forKey:@"substring"];
|
|
[dict setObject:dictionaryFromNSRange(segment.substringRange) forKey:@"substringRange"];
|
|
[dict setObject:@(segment.timestamp) forKey:@"timestamp"];
|
|
[dict setObject:@(segment.duration) forKey:@"duration"];
|
|
[dict setObject:@(segment.confidence) forKey:@"confidence"];
|
|
[dict setObject:segment.alternativeSubstrings.copy forKey:@"alternativeSubstrings"];
|
|
|
|
if (@available(iOS 14.5, *)) { }
|
|
else {
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
[dict setObject:dictionaryFromSFVoiceAnalytics(segment.voiceAnalytics) forKey:@"voiceAnalytics"];
|
|
#pragma clang diagnostic pop
|
|
}
|
|
|
|
return [dict copy];
|
|
}
|
|
|
|
typedef id (*mapFunction)(id);
|
|
static NSArray *mapArray(NSArray *input, mapFunction function) {
|
|
NSMutableArray *result = [NSMutableArray arrayWithCapacity:[input count]];
|
|
for (id value in input) {
|
|
[result addObject:function(value)];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
static NSDictionary *dictionaryFromSFTranscription(SFTranscription *transcription) {
|
|
|
|
if (transcription == nil) { return @{}; };
|
|
|
|
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
|
|
|
[dict setObject:transcription.formattedString forKey:@"formattedString"];
|
|
[dict setObject:mapArray(transcription.segments, dictionaryFromSFTranscriptionSegment) forKey:@"segments"];
|
|
|
|
if (@available(iOS 14.5, *)) { }
|
|
else {
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
[dict setObject:@(transcription.speakingRate) forKey:@"speakingRate"];
|
|
[dict setObject:@(transcription.averagePauseDuration) forKey:@"averagePauseDuration"];
|
|
#pragma clang diagnostic pop
|
|
}
|
|
|
|
return [dict copy];
|
|
}
|
|
|
|
#if defined(__IPHONE_14_5) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_5
|
|
API_AVAILABLE(ios(14.5))
|
|
static NSDictionary *dictionaryFromSFSpeechRecognitionMetadata(SFSpeechRecognitionMetadata *metadata) {
|
|
if (metadata == nil) { return @{}; }
|
|
return @{
|
|
@"speakingRate": @(metadata.speakingRate),
|
|
@"averagePauseDuration": @(metadata.averagePauseDuration),
|
|
@"speechStartTimestamp": @(metadata.speechStartTimestamp),
|
|
@"speechDuration": @(metadata.speechDuration),
|
|
@"voiceAnalytics": dictionaryFromSFVoiceAnalytics(metadata.voiceAnalytics)
|
|
};
|
|
}
|
|
#endif
|
|
|
|
static NSDictionary *dictionaryFromCGSize(CGSize s) {
|
|
return @{ @"h": @(s.height), @"w": @(s.width) };
|
|
}
|
|
|
|
static NSDictionary *dictionaryFromCGRect(CGRect r) {
|
|
return @{ @"origin": dictionaryFromCGPoint(r.origin), @"size": dictionaryFromCGSize(r.size) };
|
|
}
|
|
|
|
static NSDictionary *dictionaryFromUIEdgeInsets(UIEdgeInsets i) {
|
|
return @{ @"top": @(i.top), @"left": @(i.left), @"bottom": @(i.bottom), @"right": @(i.right) };
|
|
}
|
|
|
|
static CGSize sizeFromDictionary(NSDictionary *dict) {
|
|
return (CGSize){.width = ((NSNumber *)dict[@"w"]).doubleValue, .height = ((NSNumber *)dict[@"h"]).doubleValue };
|
|
}
|
|
|
|
static CGPoint pointFromDictionary(NSDictionary *dict) {
|
|
return (CGPoint){.x = ((NSNumber *)dict[@"x"]).doubleValue, .y = ((NSNumber *)dict[@"y"]).doubleValue};
|
|
}
|
|
|
|
static CGRect rectFromDictionary(NSDictionary *dict) {
|
|
return (CGRect){.origin = pointFromDictionary(dict[@"origin"]), .size = sizeFromDictionary(dict[@"size"])};
|
|
}
|
|
|
|
static UIEdgeInsets edgeInsetsFromDictionary(NSDictionary *dict) {
|
|
return (UIEdgeInsets){.top = ((NSNumber *)dict[@"top"]).doubleValue, .left = ((NSNumber *)dict[@"left"]).doubleValue, .bottom = ((NSNumber *)dict[@"bottom"]).doubleValue, .right = ((NSNumber *)dict[@"right"]).doubleValue};
|
|
}
|
|
|
|
static ORKNumericAnswerStyle ORKNumericAnswerStyleFromString(NSString *s) {
|
|
return tableMapReverse(s, ORKNumericAnswerStyleTable());
|
|
}
|
|
|
|
static NSString *ORKNumericAnswerStyleToString(ORKNumericAnswerStyle style) {
|
|
return tableMapForward(style, ORKNumericAnswerStyleTable());
|
|
}
|
|
|
|
static ORKNumericAnswerStyle ORKImageChoiceAnswerStyleFromString(NSString *s) {
|
|
return tableMapReverse(s, ORKImageChoiceAnswerStyleTable());
|
|
}
|
|
|
|
static NSString *ORKImageChoiceAnswerStyleToString(ORKNumericAnswerStyle style) {
|
|
return tableMapForward(style, ORKImageChoiceAnswerStyleTable());
|
|
}
|
|
|
|
static ORKMeasurementSystem ORKMeasurementSystemFromString(NSString *s) {
|
|
return tableMapReverse(s, ORKMeasurementSystemTable());
|
|
}
|
|
|
|
static NSString *ORKMeasurementSystemToString(ORKMeasurementSystem measurementSystem) {
|
|
return tableMapForward(measurementSystem, ORKMeasurementSystemTable());
|
|
}
|
|
|
|
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
|
static NSDictionary *dictionaryFromCoordinate (CLLocationCoordinate2D coordinate) {
|
|
return @{ @"latitude": @(coordinate.latitude), @"longitude": @(coordinate.longitude) };
|
|
}
|
|
|
|
static CLLocationCoordinate2D coordinateFromDictionary(NSDictionary *dict) {
|
|
return (CLLocationCoordinate2D){.latitude = ((NSNumber *)dict[@"latitude"]).doubleValue, .longitude = ((NSNumber *)dict[@"longitude"]).doubleValue };
|
|
}
|
|
|
|
static NSDictionary *dictionaryFromCircularRegion(CLCircularRegion *region) {
|
|
NSDictionary *dictionary = region ?
|
|
@{
|
|
@"coordinate": dictionaryFromCoordinate(region.center),
|
|
@"radius": @(region.radius),
|
|
@"identifier": region.identifier
|
|
} :
|
|
@{};
|
|
return dictionary;
|
|
}
|
|
|
|
static NSDictionary *dictionaryFromPostalAddress(CNPostalAddress *address) {
|
|
return @{ @"city": address.city, @"street": address.street };
|
|
}
|
|
#endif
|
|
|
|
static NSString *identifierFromClinicalType(HKClinicalType *type) {
|
|
return type.identifier;
|
|
}
|
|
|
|
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
|
static CLCircularRegion *circularRegionFromDictionary(NSDictionary *dict) {
|
|
CLCircularRegion *circularRegion;
|
|
if (dict.count == 3) {
|
|
circularRegion = [[CLCircularRegion alloc] initWithCenter:coordinateFromDictionary(dict[@"coordinate"])
|
|
radius:((NSNumber *)dict[@"radius"]).doubleValue
|
|
identifier:dict[@"identifier"]];
|
|
}
|
|
return circularRegion;
|
|
}
|
|
#endif
|
|
|
|
static NSArray *arrayFromRegularExpressionOptions(NSRegularExpressionOptions regularExpressionOptions) {
|
|
NSMutableArray *optionsArray = [NSMutableArray new];
|
|
if (regularExpressionOptions & NSRegularExpressionCaseInsensitive) {
|
|
[optionsArray addObject:@"NSRegularExpressionCaseInsensitive"];
|
|
}
|
|
if (regularExpressionOptions & NSRegularExpressionAllowCommentsAndWhitespace) {
|
|
[optionsArray addObject:@"NSRegularExpressionAllowCommentsAndWhitespace"];
|
|
}
|
|
if (regularExpressionOptions & NSRegularExpressionIgnoreMetacharacters) {
|
|
[optionsArray addObject:@"NSRegularExpressionIgnoreMetacharacters"];
|
|
}
|
|
if (regularExpressionOptions & NSRegularExpressionDotMatchesLineSeparators) {
|
|
[optionsArray addObject:@"NSRegularExpressionDotMatchesLineSeparators"];
|
|
}
|
|
if (regularExpressionOptions & NSRegularExpressionAnchorsMatchLines) {
|
|
[optionsArray addObject:@"NSRegularExpressionAnchorsMatchLines"];
|
|
}
|
|
if (regularExpressionOptions & NSRegularExpressionUseUnixLineSeparators) {
|
|
[optionsArray addObject:@"NSRegularExpressionUseUnixLineSeparators"];
|
|
}
|
|
if (regularExpressionOptions & NSRegularExpressionUseUnicodeWordBoundaries) {
|
|
[optionsArray addObject:@"NSRegularExpressionUseUnicodeWordBoundaries"];
|
|
}
|
|
return [optionsArray copy];
|
|
}
|
|
|
|
static NSRegularExpressionOptions regularExpressionOptionsFromArray(NSArray *array) {
|
|
NSRegularExpressionOptions regularExpressionOptions = 0;
|
|
for (NSString *optionString in array) {
|
|
if ([optionString isEqualToString:@"NSRegularExpressionCaseInsensitive"]) {
|
|
regularExpressionOptions |= NSRegularExpressionCaseInsensitive;
|
|
}
|
|
else if ([optionString isEqualToString:@"NSRegularExpressionAllowCommentsAndWhitespace"]) {
|
|
regularExpressionOptions |= NSRegularExpressionAllowCommentsAndWhitespace;
|
|
}
|
|
else if ([optionString isEqualToString:@"NSRegularExpressionIgnoreMetacharacters"]) {
|
|
regularExpressionOptions |= NSRegularExpressionIgnoreMetacharacters;
|
|
}
|
|
else if ([optionString isEqualToString:@"NSRegularExpressionDotMatchesLineSeparators"]) {
|
|
regularExpressionOptions |= NSRegularExpressionDotMatchesLineSeparators;
|
|
}
|
|
else if ([optionString isEqualToString:@"NSRegularExpressionAnchorsMatchLines"]) {
|
|
regularExpressionOptions |= NSRegularExpressionAnchorsMatchLines;
|
|
}
|
|
else if ([optionString isEqualToString:@"NSRegularExpressionUseUnixLineSeparators"]) {
|
|
regularExpressionOptions |= NSRegularExpressionUseUnixLineSeparators;
|
|
}
|
|
else if ([optionString isEqualToString:@"NSRegularExpressionUseUnicodeWordBoundaries"]) {
|
|
regularExpressionOptions |= NSRegularExpressionUseUnicodeWordBoundaries;
|
|
}
|
|
}
|
|
return regularExpressionOptions;
|
|
}
|
|
|
|
static NSDictionary *dictionaryFromRegularExpression(NSRegularExpression *regularExpression) {
|
|
NSDictionary *dictionary = regularExpression ?
|
|
@{
|
|
@"pattern": regularExpression.pattern ?: @"",
|
|
@"options": arrayFromRegularExpressionOptions(regularExpression.options)
|
|
} :
|
|
@{};
|
|
return dictionary;
|
|
}
|
|
|
|
static NSRegularExpression *regularExpressionsFromDictionary(NSDictionary *dict) {
|
|
NSRegularExpression *regularExpression;
|
|
if (dict.count == 2) {
|
|
regularExpression = [NSRegularExpression regularExpressionWithPattern:dict[@"pattern"]
|
|
options:regularExpressionOptionsFromArray(dict[@"options"])
|
|
error:nil];
|
|
}
|
|
return regularExpression;
|
|
}
|
|
|
|
static NSDictionary *dictionaryFromPasswordRules(UITextInputPasswordRules *passwordRules) {
|
|
NSDictionary *dictionary = passwordRules ?
|
|
@{
|
|
@"rules": passwordRules.passwordRulesDescriptor ?: @""
|
|
} :
|
|
@{};
|
|
return dictionary;
|
|
}
|
|
|
|
static UITextInputPasswordRules *passwordRulesFromDictionary(NSDictionary *dict) {
|
|
UITextInputPasswordRules *passwordRules;
|
|
if (dict.count == 1) {
|
|
passwordRules = [UITextInputPasswordRules passwordRulesWithDescriptor:dict[@"rules"]];
|
|
}
|
|
return passwordRules;
|
|
}
|
|
|
|
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
|
static CNPostalAddress *postalAddressFromDictionary(NSDictionary *dict) {
|
|
CNMutablePostalAddress *postalAddress = [[CNMutablePostalAddress alloc] init];
|
|
postalAddress.city = dict[@"city"];
|
|
postalAddress.street = dict[@"street"];
|
|
return [postalAddress copy];
|
|
}
|
|
#endif
|
|
|
|
static HKClinicalType *typeFromIdentifier(NSString *identifier) {
|
|
return [HKClinicalType clinicalTypeForIdentifier:identifier];
|
|
}
|
|
|
|
static UIColor * _Nullable colorFromDictionary(NSDictionary *dict) {
|
|
CGFloat r = [[dict objectForKey:@"r"] floatValue];
|
|
CGFloat g = [[dict objectForKey:@"g"] floatValue];
|
|
CGFloat b = [[dict objectForKey:@"b"] floatValue];
|
|
CGFloat a = [[dict objectForKey:@"a"] floatValue];
|
|
return [UIColor colorWithRed:r green:g blue:b alpha:a];
|
|
}
|
|
|
|
static NSDictionary * _Nullable dictionaryFromColor(UIColor *color) {
|
|
CGFloat r, g, b, a;
|
|
if ([color getRed:&r green:&g blue:&b alpha:&a]) {
|
|
return @{@"r":@(r), @"g":@(g), @"b":@(b), @"a":@(a)};
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
static NSMutableDictionary *ORKESerializationEncodingTable(void);
|
|
static id propFromDict(NSDictionary *dict, NSString *propName, ORKESerializationContext *context);
|
|
static NSArray *classEncodingsForClass(Class c) ;
|
|
static id objectForJsonObject(id input, Class expectedClass, ORKESerializationJSONToObjectBlock converterBlock, ORKESerializationContext *context);
|
|
|
|
__unused static NSInteger const SerializationVersion = 1; // Will be used moving forward as we get additional versions
|
|
|
|
#define ESTRINGIFY2(x) #x
|
|
#define ESTRINGIFY(x) ESTRINGIFY2(x)
|
|
|
|
#define ENTRY(entryName, mInitBlock, mProperties) \
|
|
@ESTRINGIFY(entryName) : [[ORKESerializableTableEntry alloc] initWithClass: [entryName class] \
|
|
initBlock: mInitBlock \
|
|
properties: mProperties]
|
|
|
|
#define PROPERTY(propertyName, mValueClass, mContainerClass, mWriteAfterInit, mObjectToJSONBlock, mJsonToObjectBlock) \
|
|
@ESTRINGIFY(propertyName) : ([[ORKESerializableProperty alloc] initWithPropertyName: @ESTRINGIFY(propertyName) \
|
|
valueClass: [mValueClass class] \
|
|
containerClass: [mContainerClass class] \
|
|
writeAfterInit: mWriteAfterInit \
|
|
objectToJSONBlock: mObjectToJSONBlock \
|
|
jsonToObjectBlock: mJsonToObjectBlock \
|
|
skipSerialization: NO])
|
|
|
|
#define SKIP_PROPERTY(propertyName, mValueClass, mContainerClass, mWriteAfterInit, mObjectToJSONBlock, mJsonToObjectBlock) \
|
|
@ESTRINGIFY(propertyName) : ([[ORKESerializableProperty alloc] initWithPropertyName: @ESTRINGIFY(propertyName) \
|
|
valueClass: [mValueClass class] \
|
|
containerClass: [mContainerClass class] \
|
|
writeAfterInit: mWriteAfterInit \
|
|
objectToJSONBlock: mObjectToJSONBlock \
|
|
jsonToObjectBlock: mJsonToObjectBlock \
|
|
skipSerialization: YES])
|
|
|
|
#define IMAGEPROPERTY(propertyName, containerClass, writeAfterInit) @ESTRINGIFY(propertyName) : \
|
|
imagePropertyObject(@ESTRINGIFY(propertyName), \
|
|
[containerClass class], \
|
|
writeAfterInit, \
|
|
NO)
|
|
|
|
#define DYNAMICCAST(x, c) ((c *) ([x isKindOfClass:[c class]] ? x : nil))
|
|
|
|
@class ORKESerializableProperty;
|
|
|
|
@interface ORKESerializableTableEntry : NSObject
|
|
|
|
- (instancetype)init NS_UNAVAILABLE;
|
|
|
|
- (instancetype)initWithClass:(Class)class
|
|
initBlock:(ORKESerializationInitBlock)initBlock
|
|
properties:(NSDictionary<NSString *, ORKESerializableProperty *> *)properties NS_DESIGNATED_INITIALIZER;
|
|
|
|
@property (nonatomic) Class class;
|
|
@property (nonatomic, copy) ORKESerializationInitBlock initBlock;
|
|
@property (nonatomic, strong) NSMutableDictionary<NSString *, ORKESerializableProperty *> *properties;
|
|
|
|
@end
|
|
|
|
|
|
@implementation ORKESerializationBundleImageProvider
|
|
|
|
- (instancetype)initWithBundle:(NSBundle *)bundle {
|
|
self = [super init];
|
|
if (self) {
|
|
_bundle = bundle;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (UIImage *)imageForReference:(NSDictionary *)reference {
|
|
NSString *imageName = [reference objectForKey:ORKESerializationKeyImageName];
|
|
// Try to get a system symbol image first
|
|
UIImage *image = [UIImage systemImageNamed:imageName];
|
|
if (image == nil) {
|
|
image = [UIImage imageNamed:imageName inBundle:_bundle compatibleWithTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceIdiom:[UIDevice currentDevice].userInterfaceIdiom]];
|
|
}
|
|
return image;
|
|
}
|
|
|
|
// Writing to bundle is not supported: supply a placeholder
|
|
- (nullable NSDictionary *)referenceBySavingImage:(UIImage __unused *)image {
|
|
return @{ORKESerializationKeyImageName : @""};
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
@implementation ORKESerializationPropertyModifier
|
|
|
|
- (instancetype)initWithKeypath:(NSString *)keypath value:(id)value type:(ORKESerializationPropertyModifierType)type {
|
|
self = [super init];
|
|
if (self) {
|
|
_keypath = [keypath copy];
|
|
_value = [value copy];
|
|
_type = type;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation ORKESerializationPropertyInjector
|
|
|
|
- (instancetype)initWithBasePath:(NSString *)basePath modifiers:(NSArray<ORKESerializationPropertyModifier *> *)modifiers {
|
|
self = [super init];
|
|
if (self) {
|
|
_basePath = [basePath copy];
|
|
NSMutableDictionary *propertyValues = [NSMutableDictionary dictionary];
|
|
[modifiers enumerateObjectsUsingBlock:^(ORKESerializationPropertyModifier * _Nonnull obj, __unused NSUInteger idx, __unused BOOL * _Nonnull stop) {
|
|
if (obj.type == ORKESerializationPropertyModifierTypePath && [obj.value isKindOfClass:[NSString class]]) {
|
|
propertyValues[obj.keypath] = [_basePath stringByAppendingPathComponent:(NSString *)obj.value];
|
|
} else {
|
|
propertyValues[obj.keypath] = obj.value;
|
|
}
|
|
}];
|
|
_propertyValues = [propertyValues copy];
|
|
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (NSDictionary *)injectedDictionaryWithDictionary:(NSDictionary *)inputDictionary {
|
|
NSMutableDictionary *mutatedDictionary = [inputDictionary mutableCopy];
|
|
[_propertyValues enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull keypath, id _Nonnull obj, __unused BOOL * _Nonnull stop) {
|
|
NSArray<NSString *> *components = [keypath componentsSeparatedByString:@"."];
|
|
NSCAssert(components.count == 2, @"Unexpected number of components in keypath %@", keypath);
|
|
NSString *class = components[0];
|
|
NSString *key = components[1];
|
|
// Only inject the property if it's the corresponding class,and the key exists in the dictionary
|
|
if ([class isEqualToString:mutatedDictionary[_ClassKey]] && mutatedDictionary[key] != nil) {
|
|
mutatedDictionary[key] = obj;
|
|
}
|
|
}];
|
|
return [mutatedDictionary copy];
|
|
}
|
|
|
|
@end
|
|
|
|
@interface ORKESerializableProperty : NSObject
|
|
|
|
- (instancetype)initWithPropertyName:(NSString *)propertyName
|
|
valueClass:(Class)valueClass
|
|
containerClass:(Class)containerClass
|
|
writeAfterInit:(BOOL)writeAfterInit
|
|
objectToJSONBlock:(ORKESerializationObjectToJSONBlock)objectToJSON
|
|
jsonToObjectBlock:(ORKESerializationJSONToObjectBlock)jsonToObjectBlock
|
|
skipSerialization:(BOOL)skipSerialization;
|
|
|
|
@property (nonatomic, copy) NSString *propertyName;
|
|
@property (nonatomic) Class valueClass;
|
|
@property (nonatomic) Class containerClass;
|
|
@property (nonatomic) BOOL writeAfterInit;
|
|
@property (nonatomic, copy) ORKESerializationObjectToJSONBlock objectToJSONBlock;
|
|
@property (nonatomic, copy) ORKESerializationJSONToObjectBlock jsonToObjectBlock;
|
|
@property (nonatomic) BOOL skipSerialization;
|
|
|
|
@end
|
|
|
|
static ORKESerializableProperty *imagePropertyObject(NSString *propertyName,
|
|
Class containerClass,
|
|
BOOL writeAfterInit,
|
|
BOOL skipSerialization) {
|
|
return [[ORKESerializableProperty alloc] initWithPropertyName:propertyName
|
|
valueClass:[UIImage class]
|
|
containerClass:containerClass
|
|
writeAfterInit:writeAfterInit
|
|
objectToJSONBlock:^id _Nullable(id object, ORKESerializationContext *context) {
|
|
return [context.imageProvider referenceBySavingImage:object];
|
|
}
|
|
jsonToObjectBlock:^id _Nullable(id jsonObject, ORKESerializationContext *context) {
|
|
return [context.imageProvider imageForReference:jsonObject];
|
|
}
|
|
skipSerialization:skipSerialization];
|
|
}
|
|
|
|
@implementation ORKESerializableTableEntry
|
|
|
|
- (instancetype)initWithClass:(Class)class
|
|
initBlock:(ORKESerializationInitBlock)initBlock
|
|
properties:(NSDictionary *)properties {
|
|
self = [super init];
|
|
if (self) {
|
|
_class = class;
|
|
_initBlock = initBlock;
|
|
_properties = [properties mutableCopy];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
@implementation ORKESerializableProperty
|
|
|
|
- (instancetype)initWithPropertyName:(NSString *)propertyName
|
|
valueClass:(Class)valueClass
|
|
containerClass:(Class)containerClass
|
|
writeAfterInit:(BOOL)writeAfterInit
|
|
objectToJSONBlock:(ORKESerializationObjectToJSONBlock)objectToJSON
|
|
jsonToObjectBlock:(ORKESerializationJSONToObjectBlock)jsonToObjectBlock
|
|
skipSerialization:(BOOL)skipSerialization {
|
|
self = [super init];
|
|
if (self) {
|
|
_propertyName = propertyName;
|
|
_valueClass = valueClass;
|
|
_containerClass = containerClass;
|
|
_writeAfterInit = writeAfterInit;
|
|
_objectToJSONBlock = objectToJSON;
|
|
_jsonToObjectBlock = jsonToObjectBlock;
|
|
_skipSerialization = skipSerialization;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation ORKESerializationContext
|
|
|
|
- (instancetype)initWithLocalizer:(nullable id<ORKESerializationLocalizer>)localizer
|
|
imageProvider:(nullable id<ORKESerializationImageProvider>)imageProvider
|
|
stringInterpolator:(nullable id<ORKESerializationStringInterpolator>)stringInterpolator
|
|
propertyInjector:(nullable ORKESerializationPropertyInjector *)propertyInjector {
|
|
self = [super init];
|
|
if (self) {
|
|
_localizer = localizer;
|
|
_imageProvider = imageProvider;
|
|
_stringInterpolator = stringInterpolator;
|
|
_propertyInjector = propertyInjector;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
@end
|
|
|
|
static id propFromDict(NSDictionary *dict, NSString *propName, ORKESerializationContext *context) {
|
|
Class class = NSClassFromString(dict[_ClassKey]);
|
|
|
|
NSArray *classEncodings = classEncodingsForClass(class);
|
|
ORKESerializableProperty *propertyEntry = nil;
|
|
for (ORKESerializableTableEntry *classEncoding in classEncodings) {
|
|
|
|
NSDictionary *propertyEncoding = classEncoding.properties;
|
|
propertyEntry = propertyEncoding[propName];
|
|
if (propertyEntry != nil) {
|
|
break;
|
|
}
|
|
}
|
|
NSCAssert(propertyEntry != nil, @"Unexpected property %@ for class %@", propName, dict[_ClassKey]);
|
|
|
|
Class containerClass = propertyEntry.containerClass;
|
|
Class propertyClass = propertyEntry.valueClass;
|
|
ORKESerializationJSONToObjectBlock converterBlock = propertyEntry.jsonToObjectBlock;
|
|
|
|
id input = dict[propName];
|
|
id output = nil;
|
|
if (input != nil) {
|
|
if ([containerClass isSubclassOfClass:[NSArray class]]) {
|
|
NSMutableArray *outputArray = [NSMutableArray array];
|
|
for (id value in DYNAMICCAST(input, NSArray)) {
|
|
id convertedValue = objectForJsonObject(value, propertyClass, converterBlock, context);
|
|
NSCAssert(convertedValue != nil, @"Could not convert to object of class %@", propertyClass);
|
|
[outputArray addObject:convertedValue];
|
|
}
|
|
output = outputArray;
|
|
} else if ([containerClass isSubclassOfClass:[NSDictionary class]]) {
|
|
NSMutableDictionary *outputDictionary = [NSMutableDictionary dictionary];
|
|
for (NSString *key in [DYNAMICCAST(input, NSDictionary) allKeys]) {
|
|
id convertedValue = objectForJsonObject(DYNAMICCAST(input, NSDictionary)[key], propertyClass, converterBlock, nil);
|
|
NSCAssert(convertedValue != nil, @"Could not convert to object of class %@", propertyClass);
|
|
outputDictionary[key] = convertedValue;
|
|
}
|
|
output = outputDictionary;
|
|
} else {
|
|
NSCAssert(containerClass == [NSObject class], @"Unexpected container class %@", containerClass);
|
|
|
|
output = objectForJsonObject(input, propertyClass, converterBlock, context);
|
|
|
|
// Edge case for ORKAnswerFormat options. Certain formats (e.g. ORKTextChoiceAnswerFormat) contain
|
|
// text strings (e.g. 'Yes', 'No') that need to be localized but are already of the expected type.
|
|
//
|
|
// Remaining localization/interpolication is done in `objectForJsonObject`.
|
|
if ([output isKindOfClass:[NSString class]] && ![propName isEqualToString:@"identifier"]) {
|
|
id<ORKESerializationLocalizer> localizer = context.localizer;
|
|
id<ORKESerializationStringInterpolator> stringInterpolator = context.stringInterpolator;
|
|
|
|
if (localizer != nil) {
|
|
output = [localizer localizedStringForKey:output];
|
|
}
|
|
|
|
if (stringInterpolator != nil) {
|
|
output = [stringInterpolator interpolatedStringForString:output];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return output;
|
|
}
|
|
|
|
@implementation ORKESerializationBundleLocalizer
|
|
|
|
- (instancetype)initWithBundle:(NSBundle *)bundle tableName:(NSString *)tableName {
|
|
self = [super init];
|
|
if (self) {
|
|
_bundle = bundle;
|
|
_tableName = [tableName copy];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (NSString *)localizedStringForKey:(NSString *)string
|
|
{
|
|
// Keys that exist in the localization table will be localized.
|
|
//
|
|
// If the key is not found in the table the provided key string will be returned as is,
|
|
// supporting the expected functionality for inputs that contain both strings to be
|
|
// localized as well as strings to be displayed as is.
|
|
return [self.bundle localizedStringForKey:string value:string table:self.tableName];
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
#define NUMTOSTRINGBLOCK(table) ^id(id num, __unused ORKESerializationContext *context) { return table[((NSNumber *)num).unsignedIntegerValue]; }
|
|
#define STRINGTONUMBLOCK(table) ^id(id string, __unused ORKESerializationContext *context) { NSUInteger index = [table indexOfObject:string]; \
|
|
NSCAssert(index != NSNotFound, @"Expected valid entry from table %@", table); \
|
|
return @(index); \
|
|
}
|
|
|
|
@implementation ORKESerializer
|
|
|
|
static NSArray *ORKChoiceAnswerStyleTable(void) {
|
|
static NSArray *table;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
table = @[@"singleChoice", @"multipleChoice"];
|
|
});
|
|
|
|
return table;
|
|
}
|
|
|
|
static NSArray *ORKDateAnswerStyleTable(void) {
|
|
static NSArray *table = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
table = @[@"dateTime", @"date"];
|
|
});
|
|
return table;
|
|
}
|
|
|
|
static NSArray *buttonIdentifierTable(void) {
|
|
static NSArray *table = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
table = @[@"none", @"left", @"right"];
|
|
});
|
|
return table;
|
|
}
|
|
|
|
static NSArray *memoryGameStatusTable(void) {
|
|
static NSArray *table = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
table = @[@"unknown", @"success", @"failure", @"timeout"];
|
|
});
|
|
return table;
|
|
}
|
|
|
|
static NSArray *numberFormattingStyleTable(void) {
|
|
static NSArray *table = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
table = @[@"default", @"percent"];
|
|
});
|
|
return table;
|
|
}
|
|
|
|
static NSDictionary *dictionaryForORKSpeechRecognitionResult(void) {
|
|
|
|
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
|
|
|
[dict addEntriesFromDictionary:@{PROPERTY(transcription, SFTranscription, NSObject, NO,
|
|
(^id(id transcription, __unused ORKESerializationContext *context) { return dictionaryFromSFTranscription(transcription); }),
|
|
// Decode not supported: SFTranscription is immmutable
|
|
(^id(id __unused transcriptionDict, __unused ORKESerializationContext *context) { return nil; }))}];
|
|
#if defined(__IPHONE_14_5) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_5
|
|
if (@available(iOS 14.5, *)) {
|
|
[dict addEntriesFromDictionary:@{PROPERTY(recognitionMetadata, SFSpeechRecognitionMetadata, NSObject, NO,
|
|
(^id(id recognitionMetadata, __unused ORKESerializationContext *context) { return dictionaryFromSFSpeechRecognitionMetadata(recognitionMetadata); }),
|
|
(^id(id __unused recognitionMetadataDict, __unused ORKESerializationContext *context) { return nil; }))}];
|
|
}
|
|
#endif
|
|
|
|
return [dict copy];
|
|
}
|
|
|
|
#define GETPROP(d,x) getter(d, @ESTRINGIFY(x))
|
|
static NSMutableDictionary<NSString *, ORKESerializableTableEntry *> *ORKESerializationEncodingTable(void) {
|
|
static dispatch_once_t onceToken;
|
|
static NSMutableDictionary<NSString *, ORKESerializableTableEntry *> *internalEncodingTable = nil;
|
|
dispatch_once(&onceToken, ^{
|
|
internalEncodingTable =
|
|
[@{
|
|
ENTRY(ORKResultSelector,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKResultSelector *selector = [[ORKResultSelector alloc] initWithTaskIdentifier:GETPROP(dict, taskIdentifier)
|
|
stepIdentifier:GETPROP(dict, stepIdentifier)
|
|
resultIdentifier:GETPROP(dict, resultIdentifier)];
|
|
return selector;
|
|
},
|
|
(@{
|
|
PROPERTY(taskIdentifier, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(stepIdentifier, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(resultIdentifier, NSString, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKPredicateStepNavigationRule,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKPredicateStepNavigationRule *rule = [[ORKPredicateStepNavigationRule alloc] initWithResultPredicates:GETPROP(dict, resultPredicates)
|
|
destinationStepIdentifiers:GETPROP(dict, destinationStepIdentifiers)
|
|
defaultStepIdentifier:GETPROP(dict, defaultStepIdentifier)
|
|
validateArrays:NO];
|
|
return rule;
|
|
},
|
|
(@{
|
|
PROPERTY(resultPredicates, NSPredicate, NSArray, NO, nil, nil),
|
|
PROPERTY(destinationStepIdentifiers, NSString, NSArray, NO, nil, nil),
|
|
PROPERTY(defaultStepIdentifier, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(additionalTaskResults, ORKTaskResult, NSArray, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKDirectStepNavigationRule,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKDirectStepNavigationRule *rule = [[ORKDirectStepNavigationRule alloc] initWithDestinationStepIdentifier:GETPROP(dict, destinationStepIdentifier)];
|
|
return rule;
|
|
},
|
|
(@{
|
|
PROPERTY(destinationStepIdentifier, NSString, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKPredicateFormItemVisibilityRule,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
NSString* predicateFormat = GETPROP(dict, predicateFormat);
|
|
ORKPredicateFormItemVisibilityRule *rule = [[ORKPredicateFormItemVisibilityRule alloc] initWithPredicateFormat:predicateFormat];
|
|
return rule;
|
|
},
|
|
(@{
|
|
PROPERTY(predicateFormat, NSString, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKAudioLevelNavigationRule,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKAudioLevelNavigationRule *rule = [[ORKAudioLevelNavigationRule alloc] initWithAudioLevelStepIdentifier:GETPROP(dict, audioLevelStepIdentifier) destinationStepIdentifier:GETPROP(dict, destinationStepIdentifier)
|
|
recordingSettings:GETPROP(dict, recordingSettings)];
|
|
return rule;
|
|
},
|
|
(@{
|
|
PROPERTY(audioLevelStepIdentifier, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(destinationStepIdentifier, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(recordingSettings, NSDictionary, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKOrderedTask,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKOrderedTask *task = [[ORKOrderedTask alloc] initWithIdentifier:GETPROP(dict, identifier)
|
|
steps:GETPROP(dict, steps)];
|
|
return task;
|
|
},
|
|
(@{
|
|
PROPERTY(identifier, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(steps, ORKStep, NSArray, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKNavigableOrderedTask,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKNavigableOrderedTask *task = [[ORKNavigableOrderedTask alloc] initWithIdentifier:GETPROP(dict, identifier)
|
|
steps:GETPROP(dict, steps)];
|
|
return task;
|
|
},
|
|
(@{
|
|
PROPERTY(stepNavigationRules, ORKStepNavigationRule, NSMutableDictionary, YES, nil, nil),
|
|
PROPERTY(skipStepNavigationRules, ORKSkipStepNavigationRule, NSMutableDictionary, YES, nil, nil),
|
|
PROPERTY(stepModifiers, ORKStepModifier, NSMutableDictionary, YES, nil, nil),
|
|
PROPERTY(shouldReportProgress, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKStep *step = [[ORKStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
return step;
|
|
},
|
|
(@{
|
|
PROPERTY(identifier, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(optional, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(title, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(text, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(detailText, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(headerTextAlignment, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(footnote, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(shouldTintImages, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(useSurveyMode, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(bodyItems, ORKBodyItem, NSArray, YES, nil, nil),
|
|
PROPERTY(imageContentMode, NSNumber, NSObject, YES, nil, nil),
|
|
IMAGEPROPERTY(iconImage, NSObject, YES),
|
|
IMAGEPROPERTY(auxiliaryImage, NSObject, YES),
|
|
IMAGEPROPERTY(image, NSObject, YES),
|
|
PROPERTY(bodyItemTextAlignment, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(buildInBodyItems, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(useExtendedPadding, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(earlyTerminationConfiguration, ORKEarlyTerminationConfiguration, NSObject, YES, nil, nil),
|
|
PROPERTY(shouldAutomaticallyAdjustImageTintColor, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKBodyItem,
|
|
^id(__unused NSDictionary *dict, __unused ORKESerializationPropertyGetter getter) {
|
|
ORKBodyItem *bodyItem = [[ORKBodyItem alloc] initWithText:GETPROP(dict, text)
|
|
detailText:GETPROP(dict, detailText)
|
|
image:nil
|
|
learnMoreItem:GETPROP(dict, learnMoreItem)
|
|
bodyItemStyle:[GETPROP(dict, bodyItemStyle) intValue]
|
|
useCardStyle:GETPROP(dict, useCardStyle)
|
|
alignImageToTop:GETPROP(dict, alignImageToTop)];
|
|
return bodyItem;
|
|
},
|
|
(@{
|
|
PROPERTY(text, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(detailText, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(bodyItemStyle, NSNumber, NSObject, NO, nil, nil),
|
|
IMAGEPROPERTY(image, NSObject, YES),
|
|
PROPERTY(learnMoreItem, ORKLearnMoreItem, NSObject, YES, nil, nil),
|
|
PROPERTY(useCardStyle, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(useSecondaryColor, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(alignImageToTop, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKLearnMoreItem,
|
|
^id(__unused NSDictionary *dict, __unused ORKESerializationPropertyGetter getter) {
|
|
ORKLearnMoreItem *learnMoreItem = [[ORKLearnMoreItem alloc] initWithText:GETPROP(dict, text) learnMoreInstructionStep:GETPROP(dict, learnMoreInstructionStep)];
|
|
return learnMoreItem;
|
|
},
|
|
(@{
|
|
PROPERTY(text, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(learnMoreInstructionStep, ORKLearnMoreInstructionStep, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKEarlyTerminationConfiguration,
|
|
^id(__unused NSDictionary *dict, __unused ORKESerializationPropertyGetter getter) {
|
|
ORKEarlyTerminationConfiguration *configuration = [[ORKEarlyTerminationConfiguration alloc] initWithButtonText:GETPROP(dict, buttonText)
|
|
earlyTerminationStep:GETPROP(dict, earlyTerminationStep)];
|
|
return configuration;
|
|
},
|
|
(@{
|
|
PROPERTY(buttonText, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(earlyTerminationStep, ORKStep, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKReviewStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKReviewStep *reviewStep = [ORKReviewStep standaloneReviewStepWithIdentifier:GETPROP(dict, identifier)
|
|
steps:GETPROP(dict, steps)
|
|
resultSource:GETPROP(dict, resultSource)];
|
|
return reviewStep;
|
|
},
|
|
(@{
|
|
PROPERTY(steps, ORKStep, NSArray, NO, nil, nil),
|
|
PROPERTY(resultSource, ORKTaskResult, NSObject, NO, nil, nil),
|
|
PROPERTY(excludeInstructionSteps, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKPDFViewerStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKPDFViewerStep alloc] initWithIdentifier:GETPROP(dict, identifier)
|
|
pdfURL:GETPROP(dict, pdfURL)];
|
|
},
|
|
(@{
|
|
PROPERTY(pdfURL, NSURL, NSObject, YES,
|
|
^id(id url, __unused ORKESerializationContext *context) { return [(NSURL *)url absoluteString]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [NSURL URLWithString:string]; }),
|
|
PROPERTY(actionBarOption, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKPasscodeStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKPasscodeStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(passcodeType, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(useBiometrics, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(passcodeFlow, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKWaitStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKWaitStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(indicatorType, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKRecorderConfiguration,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKRecorderConfiguration *recorderConfiguration = [[ORKRecorderConfiguration alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
return recorderConfiguration;
|
|
},
|
|
(@{
|
|
PROPERTY(identifier, NSString, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKQuestionStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKQuestionStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(answerFormat, ORKAnswerFormat, NSObject, YES, nil, nil),
|
|
PROPERTY(placeholder, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(question, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(useCardView, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(learnMoreItem, ORKLearnMoreItem, NSObject, YES, nil, nil),
|
|
PROPERTY(tagText, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(presentationStyle, NSString, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKInstructionStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKInstructionStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(detailText, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(footnote, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(centerImageVertically, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKLearnMoreInstructionStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKLearnMoreInstructionStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
})),
|
|
ENTRY(ORKSecondaryTaskStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKSecondaryTaskStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(secondaryTask, ORKOrderedTask, NSObject, YES, nil, nil),
|
|
PROPERTY(secondaryTaskButtonTitle, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(nextButtonTitle, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(requiredAttempts, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKVideoInstructionStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKVideoInstructionStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(videoURL, NSURL, NSObject, YES,
|
|
^id(id url, __unused ORKESerializationContext *context) { return [(NSURL *)url absoluteString]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [NSURL URLWithString:string]; }),
|
|
PROPERTY(thumbnailTime, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(bundleAsset, ORKBundleAsset, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKCompletionStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKCompletionStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(reasonForCompletion, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKCountdownStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKCountdownStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
})),
|
|
ENTRY(ORKTouchAnywhereStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTouchAnywhereStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
})),
|
|
ENTRY(ORKWebViewStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKWebViewStep *step = [[ORKWebViewStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
return step;
|
|
},
|
|
(@{
|
|
PROPERTY(html, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(instructionSteps, ORKInstructionStep, NSArray, YES, nil, nil),
|
|
PROPERTY(customCSS, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(showSignatureAfterContent, NSNumber, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKWebViewStepResult,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKWebViewStepResult *result = [[ORKWebViewStepResult alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
return result;
|
|
},
|
|
(@{
|
|
PROPERTY(result, NSString, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKHealthQuantityTypeRecorderConfiguration,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKHealthQuantityTypeRecorderConfiguration alloc] initWithIdentifier:GETPROP(dict, identifier) healthQuantityType:GETPROP(dict, quantityType) unit:GETPROP(dict, unit)];
|
|
},
|
|
(@{
|
|
PROPERTY(quantityType, HKQuantityType, NSObject, NO,
|
|
^id(id type, __unused ORKESerializationContext *context) { return [(HKQuantityType *)type identifier]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [HKQuantityType quantityTypeForIdentifier:string]; }),
|
|
PROPERTY(unit, HKUnit, NSObject, NO,
|
|
^id(id unit, __unused ORKESerializationContext *context) { return [(HKUnit *)unit unitString]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [HKUnit unitFromString:string]; }),
|
|
})),
|
|
ENTRY(ORKActiveStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKActiveStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(stepDuration, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(shouldShowDefaultTimer, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(shouldSpeakCountDown, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(shouldSpeakRemainingTimeAtHalfway, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(shouldStartTimerAutomatically, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(shouldPlaySoundOnStart, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(shouldPlaySoundOnFinish, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(shouldVibrateOnStart, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(shouldVibrateOnFinish, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(shouldUseNextAsSkipButton, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(shouldContinueOnFinish, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(spokenInstruction, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(finishedSpokenInstruction, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(recorderConfigurations, ORKRecorderConfiguration, NSArray, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKAudioStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKAudioStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(useRecordButton, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKToneAudiometryStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKToneAudiometryStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
((@{
|
|
PROPERTY(toneDuration, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(practiceStep, NSNumber, NSObject, YES, nil, nil),
|
|
}))),
|
|
ENTRY(ORKdBHLToneAudiometryStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKdBHLToneAudiometryStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(toneDuration, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(maxRandomPreStimulusDelay, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(postStimulusDelay, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(maxNumberOfTransitionsPerFrequency, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(initialdBHLValue, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(dBHLStepUpSize, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(dBHLStepUpSizeFirstMiss, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(dBHLStepUpSizeSecondMiss, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(dBHLStepUpSizeThirdMiss, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(dBHLStepDownSize, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(dBHLMinimumThreshold, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(headphoneType, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(earPreference, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(frequencyList, NSArray, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKHolePegTestPlaceStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKHolePegTestPlaceStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(movingDirection, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(dominantHandTested, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(numberOfPegs, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(threshold, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(rotated, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKHolePegTestRemoveStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKHolePegTestRemoveStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(movingDirection, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(dominantHandTested, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(numberOfPegs, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(threshold, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKImageCaptureStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKImageCaptureStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(templateImageInsets, NSValue, NSObject, YES,
|
|
^id(id value, __unused ORKESerializationContext *context) { return value?dictionaryFromUIEdgeInsets(((NSValue *)value).UIEdgeInsetsValue):nil; },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return [NSValue valueWithUIEdgeInsets:edgeInsetsFromDictionary(dict)]; }),
|
|
PROPERTY(accessibilityHint, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(accessibilityInstructions, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(captureRaw, NSNumber, NSObject, YES, nil, nil),
|
|
IMAGEPROPERTY(templateImage, NSObject, YES),
|
|
})),
|
|
ENTRY(ORKVideoCaptureStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKVideoCaptureStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(templateImageInsets, NSValue, NSObject, YES,
|
|
^id(id value, __unused ORKESerializationContext *context) { return value?dictionaryFromUIEdgeInsets(((NSValue *)value).UIEdgeInsetsValue):nil; },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return [NSValue valueWithUIEdgeInsets:edgeInsetsFromDictionary(dict)]; }),
|
|
PROPERTY(duration, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(audioMute, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(torchMode, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(devicePosition, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(accessibilityHint, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(accessibilityInstructions, NSString, NSObject, YES, nil, nil),
|
|
IMAGEPROPERTY(templateImage, NSObject, YES),
|
|
})),
|
|
ENTRY(ORKSignatureStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKSignatureStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
})),
|
|
ENTRY(ORKSpatialSpanMemoryStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKSpatialSpanMemoryStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(initialSpan, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(minimumSpan, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(maximumSpan, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(playSpeed, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(maximumTests, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(maximumConsecutiveFailures, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(requireReversal, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(customTargetPluralName, NSString, NSObject, YES, nil, nil),
|
|
IMAGEPROPERTY(customTargetImage, NSObject, YES),
|
|
})),
|
|
ENTRY(ORKWalkingTaskStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKWalkingTaskStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(numberOfStepsPerLeg, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKTableStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTableStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
((@{
|
|
PROPERTY(items, NSObject, NSArray, YES, nil, nil),
|
|
PROPERTY(isBulleted, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(bulletIconNames, NSString, NSArray, YES, nil, nil),
|
|
PROPERTY(allowsSelection, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(bulletType, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(pinNavigationContainer, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(bottomPadding, NSNumber, NSObject, YES, nil, nil)
|
|
}))),
|
|
ENTRY(ORKTimedWalkStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTimedWalkStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(distanceInMeters, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKPSATStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKPSATStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(presentationMode, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(interStimulusInterval, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(stimulusDuration, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(seriesLength, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKRangeOfMotionStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKRangeOfMotionStep alloc] initWithIdentifier:GETPROP(dict, identifier) limbOption:(NSUInteger)[GETPROP(dict, identifier) integerValue]];
|
|
},
|
|
(@{
|
|
PROPERTY(limbOption, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKReactionTimeStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKReactionTimeStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(maximumStimulusInterval, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(minimumStimulusInterval, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(timeout, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(numberOfAttempts, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(thresholdAcceleration, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(successSound, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(timeoutSound, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(failureSound, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKNormalizedReactionTimeStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKNormalizedReactionTimeStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(maximumStimulusInterval, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(minimumStimulusInterval, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(timeout, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(numberOfAttempts, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(thresholdAcceleration, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(successSound, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(timeoutSound, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(failureSound, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(currentInterval, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKNormalizedReactionTimeResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(timerStartDate, NSDate, NSObject, YES,
|
|
^id(id date, __unused ORKESerializationContext *context) { return ORKEStringFromDateISO8601(date); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return ORKEDateFromStringISO8601(string); }),
|
|
PROPERTY(timerEndDate, NSDate, NSObject, YES,
|
|
^id(id date, __unused ORKESerializationContext *context) { return ORKEStringFromDateISO8601(date); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return ORKEDateFromStringISO8601(string); }),
|
|
PROPERTY(stimulusStartDate, NSDate, NSObject, YES,
|
|
^id(id date, __unused ORKESerializationContext *context) { return ORKEStringFromDateISO8601(date); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return ORKEDateFromStringISO8601(string); }),
|
|
PROPERTY(reactionDate, NSDate, NSObject, YES,
|
|
^id(id date, __unused ORKESerializationContext *context) { return ORKEStringFromDateISO8601(date); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return ORKEDateFromStringISO8601(string); }),
|
|
PROPERTY(currentInterval, NSNumber, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKStroopStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKStroopStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(numberOfAttempts, NSNumber, NSObject, YES, nil, nil)})),
|
|
ENTRY(ORKAccuracyStroopStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKAccuracyStroopStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(isColorMatching, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(baseDisplayColor, UIColor, NSObject, YES,
|
|
^id(id color, __unused ORKESerializationContext *context) { return dictionaryFromColor(color); },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return colorFromDictionary(dict); })
|
|
})),
|
|
ENTRY(ORKTappingIntervalStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTappingIntervalStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
})),
|
|
ENTRY(ORKTrailmakingStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTrailmakingStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(trailType, NSString, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKTowerOfHanoiStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTowerOfHanoiStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(numberOfDisks, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKSpeechInNoiseStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKSpeechInNoiseStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
((@{
|
|
PROPERTY(speechFilePath, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(targetSentence, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(speechFileNameWithExtension, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(noiseFileNameWithExtension, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(filterFileNameWithExtension, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(gainAppliedToNoise, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(willAudioLoop, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(hideGraphView, NSNumber, NSObject, YES, nil, nil),
|
|
}))),
|
|
ENTRY(ORKSpeechRecognitionStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKSpeechRecognitionStep alloc] initWithIdentifier:GETPROP(dict, identifier) image:nil text:GETPROP(dict, speechRecognitionText)];
|
|
},
|
|
(@{
|
|
PROPERTY(shouldHideTranscript, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(speechRecognitionText, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(speechRecognizerLocale, NSString, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKEnvironmentSPLMeterStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKEnvironmentSPLMeterStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(thresholdValue, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(samplingInterval, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(requiredContiguousSamples, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKEnvironmentSPLMeterResult,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKEnvironmentSPLMeterResult alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(sensitivityOffset, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(recordedSPLMeterSamples, NSNumber, NSArray, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKStreamingAudioRecorderConfiguration,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKStreamingAudioRecorderConfiguration alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
})),
|
|
ENTRY(ORKAudioStreamerConfiguration,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKAudioStreamerConfiguration alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
})),
|
|
ENTRY(ORKAccelerometerRecorderConfiguration,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKAccelerometerRecorderConfiguration alloc] initWithIdentifier:GETPROP(dict, identifier) frequency:((NSNumber *)GETPROP(dict, frequency)).doubleValue];
|
|
},
|
|
(@{
|
|
PROPERTY(frequency, NSNumber, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKAudioRecorderConfiguration,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKAudioRecorderConfiguration alloc] initWithIdentifier:GETPROP(dict, identifier) recorderSettings:GETPROP(dict, recorderSettings)];
|
|
},
|
|
(@{
|
|
PROPERTY(recorderSettings, NSDictionary, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKAmslerGridStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKAmslerGridStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(eyeSide, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKAmslerGridResult,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKAmslerGridResult alloc] initWithIdentifier:GETPROP(dict, identifier)image:[UIImage new] path:GETPROP(dict, path) eyeSide:(ORKAmslerGridEyeSide)[GETPROP(dict, eyeSide) integerValue]];
|
|
},
|
|
(@{
|
|
PROPERTY(eyeSide, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(path, UIBezierPath, NSArray, NO, nil, nil),
|
|
IMAGEPROPERTY(image, NSObject, YES),
|
|
})),
|
|
ENTRY(ORKConsentDocument,
|
|
nil,
|
|
(@{
|
|
PROPERTY(title, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(sections, ORKConsentSection, NSArray, NO, nil, nil),
|
|
PROPERTY(signaturePageTitle, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(signaturePageContent, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(signatures, ORKConsentSignature, NSArray, NO, nil, nil),
|
|
PROPERTY(htmlReviewContent, NSString, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKConsentSharingStep,
|
|
^(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKConsentSharingStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(localizedLearnMoreHTMLContent, NSString, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKConsentReviewStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKConsentReviewStep alloc] initWithIdentifier:GETPROP(dict, identifier) signature:GETPROP(dict, signature) inDocument:GETPROP(dict,consentDocument)];
|
|
},
|
|
(@{
|
|
PROPERTY(consentDocument, ORKConsentDocument, NSObject, NO, nil, nil),
|
|
PROPERTY(reasonForConsent, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(signature, ORKConsentSignature, NSObject, NO, nil, nil),
|
|
PROPERTY(requiresScrollToBottom, NSNumber, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKFitnessStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKFitnessStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(userInfo, NSDictionary, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKBundleAsset,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKBundleAsset alloc] initWithName:GETPROP(dict, name)
|
|
bundleIdentifier:GETPROP(dict, bundleIdentifier)
|
|
fileExtension:GETPROP(dict, fileExtension)];
|
|
},
|
|
(@{
|
|
PROPERTY(name, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(bundleIdentifier, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(fileExtension, NSString, NSObject, NO, nil, nil),
|
|
})
|
|
),
|
|
ENTRY(ORKVocalCue,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKVocalCue alloc] initWithTime:((NSNumber *)GETPROP(dict, time)).doubleValue
|
|
spokenText:GETPROP(dict, spokenText)];
|
|
},
|
|
(@{
|
|
PROPERTY(time, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(spokenText, NSString, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKAudioFitnessStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKAudioFitnessStep alloc]
|
|
initWithIdentifier:GETPROP(dict, identifier)
|
|
audioAsset:GETPROP(dict, audioAsset)
|
|
vocalCues:GETPROP(dict, vocalCues)];
|
|
},
|
|
(@{
|
|
PROPERTY(audioAsset, ORKBundleAsset, NSObject, NO, nil, nil),
|
|
PROPERTY(vocalCues, ORKVocalCue, NSArray, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKConsentSection,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKConsentSection alloc] initWithType:((NSNumber *)GETPROP(dict, type)).integerValue];
|
|
},
|
|
(@{
|
|
PROPERTY(type, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(title, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(formalTitle, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(summary, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(content, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(htmlContent, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(contentURL, NSURL, NSObject, YES,
|
|
^id(id url, __unused ORKESerializationContext *context) { return [(NSURL *)url absoluteString]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [NSURL URLWithString:string]; }),
|
|
PROPERTY(customLearnMoreButtonTitle, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(customAnimationURL, NSURL, NSObject, YES,
|
|
^id(id url, __unused ORKESerializationContext *context) { return [(NSURL *)url absoluteString]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [NSURL URLWithString:string]; }),
|
|
PROPERTY(omitFromDocument, NSNumber, NSObject, YES, nil, nil),
|
|
IMAGEPROPERTY(customImage, NSObject, YES),
|
|
})),
|
|
ENTRY(ORKConsentSignature,
|
|
nil,
|
|
(@{
|
|
PROPERTY(identifier, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(title, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(givenName, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(familyName, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(signatureDate, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(requiresName, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(requiresSignatureImage, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(signatureDateFormatString, NSString, NSObject, YES, nil, nil),
|
|
IMAGEPROPERTY(signatureImage, NSObject, YES),
|
|
})),
|
|
ENTRY(ORKRegistrationStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKRegistrationStep alloc] initWithIdentifier:GETPROP(dict, identifier) title:GETPROP(dict, title) text:GETPROP(dict, text) options:(NSUInteger)((NSNumber *)GETPROP(dict, options)).integerValue];
|
|
},
|
|
(@{
|
|
PROPERTY(options, NSNumber, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKRequestPermissionsStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKRequestPermissionsStep alloc] initWithIdentifier:GETPROP(dict, identifier) permissionTypes:GETPROP(dict, permissionTypes)];
|
|
},
|
|
(@{
|
|
PROPERTY(permissionTypes, ORKPermissionType, NSArray, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKVerificationStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKVerificationStep alloc] initWithIdentifier:GETPROP(dict, identifier) text:GETPROP(dict, text) verificationViewControllerClass:NSClassFromString(GETPROP(dict, verificationViewControllerString))];
|
|
},
|
|
(@{
|
|
PROPERTY(verificationViewControllerString, NSString, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKLoginStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKLoginStep alloc] initWithIdentifier:GETPROP(dict, identifier) title:GETPROP(dict, title) text:GETPROP(dict, text) loginViewControllerClass:NSClassFromString(GETPROP(dict, loginViewControllerString))];
|
|
},
|
|
(@{
|
|
PROPERTY(loginViewControllerString, NSString, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKDeviceMotionRecorderConfiguration,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKDeviceMotionRecorderConfiguration alloc] initWithIdentifier:GETPROP(dict, identifier) frequency:((NSNumber *)GETPROP(dict, frequency)).doubleValue];
|
|
},
|
|
(@{
|
|
PROPERTY(frequency, NSNumber, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKdBHLToneAudiometryOnboardingStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKdBHLToneAudiometryOnboardingStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(useCardView, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKFormStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKFormStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(formItems, ORKFormItem, NSArray, YES, nil, nil),
|
|
PROPERTY(footnote, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(useCardView, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(autoScrollEnabled, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(footerText, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(cardViewStyle, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKFormItem,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKFormItem* formItem = [[ORKFormItem alloc] initWithIdentifier:GETPROP(dict, identifier) text:GETPROP(dict, text) answerFormat:GETPROP(dict, answerFormat)];
|
|
return formItem;
|
|
},
|
|
(@{
|
|
PROPERTY(identifier, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(optional, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(showsProgress, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(text, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(detailText, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(placeholder, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(answerFormat, ORKAnswerFormat, NSObject, NO, nil, nil),
|
|
PROPERTY(learnMoreItem, ORKLearnMoreItem, NSObject, YES, nil, nil),
|
|
PROPERTY(tagText, NSString, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKPageStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKPageStep *step = [[ORKPageStep alloc] initWithIdentifier:GETPROP(dict, identifier) pageTask:GETPROP(dict, pageTask)];
|
|
return step;
|
|
},
|
|
(@{
|
|
PROPERTY(pageTask, ORKOrderedTask, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKNavigablePageStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKNavigablePageStep *step = [[ORKNavigablePageStep alloc] initWithIdentifier:GETPROP(dict, identifier) pageTask:GETPROP(dict, pageTask)];
|
|
return step;
|
|
},
|
|
(@{
|
|
PROPERTY(pageTask, ORKOrderedTask, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKHealthKitCharacteristicTypeAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKHealthKitCharacteristicTypeAnswerFormat alloc] initWithCharacteristicType:GETPROP(dict, characteristicType)];
|
|
},
|
|
(@{
|
|
PROPERTY(characteristicType, HKCharacteristicType, NSObject, NO,
|
|
^id(id type, __unused ORKESerializationContext *context) { return [(HKCharacteristicType *)type identifier]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [HKCharacteristicType characteristicTypeForIdentifier:string]; }),
|
|
PROPERTY(defaultDate, NSDate, NSObject, YES,
|
|
^id(id date, __unused ORKESerializationContext *context) { return [ORKResultDateTimeFormatter() stringFromDate:date]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [ORKResultDateTimeFormatter() dateFromString:string]; }),
|
|
PROPERTY(minimumDate, NSDate, NSObject, YES,
|
|
^id(id date, __unused ORKESerializationContext *context) { return [ORKResultDateTimeFormatter() stringFromDate:date]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [ORKResultDateTimeFormatter() dateFromString:string]; }),
|
|
PROPERTY(maximumDate, NSDate, NSObject, YES,
|
|
^id(id date, __unused ORKESerializationContext *context) { return [ORKResultDateTimeFormatter() stringFromDate:date]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [ORKResultDateTimeFormatter() dateFromString:string]; }),
|
|
PROPERTY(calendar, NSCalendar, NSObject, YES,
|
|
^id(id calendar, __unused ORKESerializationContext *context) { return [(NSCalendar *)calendar calendarIdentifier]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [NSCalendar calendarWithIdentifier:string]; }),
|
|
PROPERTY(shouldRequestAuthorization, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKHealthKitQuantityTypeAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKHealthKitQuantityTypeAnswerFormat alloc] initWithQuantityType:GETPROP(dict, quantityType) unit:GETPROP(dict, unit) style:((NSNumber *)GETPROP(dict, numericAnswerStyle)).integerValue];
|
|
},
|
|
(@{
|
|
PROPERTY(unit, HKUnit, NSObject, NO,
|
|
^id(id unit, __unused ORKESerializationContext *context) { return [(HKUnit *)unit unitString]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [HKUnit unitFromString:string]; }),
|
|
PROPERTY(quantityType, HKQuantityType, NSObject, NO,
|
|
^id(id type, __unused ORKESerializationContext *context) { return [(HKQuantityType *)type identifier]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [HKQuantityType quantityTypeForIdentifier:string]; }),
|
|
PROPERTY(numericAnswerStyle, NSNumber, NSObject, NO,
|
|
^id(id num, __unused ORKESerializationContext *context) { return ORKNumericAnswerStyleToString(((NSNumber *)num).integerValue); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return @(ORKNumericAnswerStyleFromString(string)); }),
|
|
PROPERTY(shouldRequestAuthorization, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKAnswerFormat,
|
|
nil,
|
|
(@{
|
|
PROPERTY(showDontKnowButton, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(customDontKnowButtonText, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(dontKnowButtonStyle, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKDontKnowAnswer,
|
|
^id(__unused NSDictionary *dict, __unused ORKESerializationPropertyGetter getter) {
|
|
return [ORKDontKnowAnswer answer];
|
|
},
|
|
(@{
|
|
})),
|
|
ENTRY(ORKValuePickerAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKValuePickerAnswerFormat alloc] initWithTextChoices:GETPROP(dict, textChoices)];
|
|
},
|
|
(@{
|
|
PROPERTY(textChoices, ORKTextChoice, NSArray, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKMultipleValuePickerAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKMultipleValuePickerAnswerFormat alloc] initWithValuePickers:GETPROP(dict, valuePickers) separator:GETPROP(dict, separator)];
|
|
},
|
|
(@{
|
|
PROPERTY(valuePickers, ORKValuePickerAnswerFormat, NSArray, NO, nil, nil),
|
|
PROPERTY(separator, NSString, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKImageChoiceAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKImageChoiceAnswerFormat alloc] initWithImageChoices:GETPROP(dict, imageChoices) style:((NSNumber *)GETPROP(dict, style)).integerValue vertical:((NSNumber *)GETPROP(dict, vertical)).boolValue];
|
|
},
|
|
(@{
|
|
PROPERTY(imageChoices, ORKImageChoice, NSArray, NO, nil, nil),
|
|
PROPERTY(style, NSNumber, NSObject, NO,
|
|
^id(id number, __unused ORKESerializationContext *context) { return ORKImageChoiceAnswerStyleToString(((NSNumber *)number).integerValue); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return @(ORKImageChoiceAnswerStyleFromString(string)); }),
|
|
PROPERTY(vertical, NSNumber, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKTextChoiceAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTextChoiceAnswerFormat alloc] initWithStyle:((NSNumber *)GETPROP(dict, style)).integerValue textChoices:GETPROP(dict, textChoices)];
|
|
},
|
|
(@{
|
|
PROPERTY(style, NSNumber, NSObject, NO, NUMTOSTRINGBLOCK(ORKChoiceAnswerStyleTable()), STRINGTONUMBLOCK(ORKChoiceAnswerStyleTable())),
|
|
PROPERTY(textChoices, ORKTextChoice, NSArray, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKTextChoice,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTextChoice alloc] initWithText:GETPROP(dict, text) detailText:GETPROP(dict, detailText) value:GETPROP(dict, value) exclusive:((NSNumber *)GETPROP(dict, exclusive)).boolValue];
|
|
},
|
|
(@{
|
|
PROPERTY(text, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(value, NSObject, NSObject, NO, nil, nil),
|
|
PROPERTY(detailText, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(exclusive, NSNumber, NSObject, NO, nil, nil),
|
|
IMAGEPROPERTY(image, NSObject, YES)
|
|
})),
|
|
ENTRY(ORKTextChoiceOther,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTextChoiceOther alloc] initWithText:GETPROP(dict, text) primaryTextAttributedString:nil detailText:GETPROP(dict, detailText) detailTextAttributedString:nil value:GETPROP(dict, value) exclusive:((NSNumber *)GETPROP(dict, exclusive)).boolValue textViewPlaceholderText:GETPROP(dict, textViewPlaceholderText) textViewInputOptional:((NSNumber *)GETPROP(dict, textViewInputOptional)).boolValue textViewStartsHidden:((NSNumber *)GETPROP(dict, textViewStartsHidden)).boolValue];
|
|
},
|
|
(@{
|
|
PROPERTY(textViewPlaceholderText, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(textViewInputOptional, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(textViewStartsHidden, NSNumber, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKImageChoice,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKImageChoice alloc] initWithNormalImage:nil selectedImage:nil text:GETPROP(dict, text) value:GETPROP(dict, value)];
|
|
},
|
|
(@{
|
|
PROPERTY(text, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(value, NSObject, NSObject, NO, nil, nil),
|
|
IMAGEPROPERTY(normalStateImage, NSObject, YES),
|
|
IMAGEPROPERTY(selectedStateImage, NSObject, YES),
|
|
})),
|
|
ENTRY(ORKTimeOfDayAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTimeOfDayAnswerFormat alloc] initWithDefaultComponents:GETPROP(dict, defaultComponents)];
|
|
},
|
|
(@{
|
|
PROPERTY(defaultComponents, NSDateComponents, NSObject, NO,
|
|
^id(id components, __unused ORKESerializationContext *context) { return ORKTimeOfDayStringFromComponents(components); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return ORKTimeOfDayComponentsFromString(string); }),
|
|
PROPERTY(minuteInterval, NSNumber, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKDateAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKDateAnswerFormat alloc] initWithStyle:((NSNumber *)GETPROP(dict, style)).integerValue defaultDate:GETPROP(dict, defaultDate) minimumDate:GETPROP(dict, minimumDate) maximumDate:GETPROP(dict, maximumDate) calendar:GETPROP(dict, calendar)];
|
|
},
|
|
(@{
|
|
PROPERTY(style, NSNumber, NSObject, NO,
|
|
NUMTOSTRINGBLOCK(ORKDateAnswerStyleTable()),
|
|
STRINGTONUMBLOCK(ORKDateAnswerStyleTable())),
|
|
PROPERTY(calendar, NSCalendar, NSObject, NO,
|
|
^id(id calendar, __unused ORKESerializationContext *context) { return [(NSCalendar *)calendar calendarIdentifier]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [NSCalendar calendarWithIdentifier:string]; }),
|
|
PROPERTY(minimumDate, NSDate, NSObject, NO,
|
|
^id(id date, __unused ORKESerializationContext *context) { return [ORKResultDateTimeFormatter() stringFromDate:date]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [ORKResultDateTimeFormatter() dateFromString:string]; }),
|
|
PROPERTY(maximumDate, NSDate, NSObject, NO,
|
|
^id(id date, __unused ORKESerializationContext *context) { return [ORKResultDateTimeFormatter() stringFromDate:date]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [ORKResultDateTimeFormatter() dateFromString:string]; }),
|
|
PROPERTY(defaultDate, NSDate, NSObject, NO,
|
|
^id(id date, __unused ORKESerializationContext *context) { return [ORKResultDateTimeFormatter() stringFromDate:date]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [ORKResultDateTimeFormatter() dateFromString:string]; }),
|
|
PROPERTY(minuteInterval, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(daysBeforeCurrentDateToSetMinimumDate, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(daysAfterCurrentDateToSetMinimumDate, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(isMaxDateCurrentTime, NSNumber, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKNumericAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
ORKNumericAnswerFormat *format = [[ORKNumericAnswerFormat alloc] initWithStyle:((NSNumber *)GETPROP(dict, style)).integerValue
|
|
unit:GETPROP(dict, unit)
|
|
displayUnit:GETPROP(dict, displayUnit)
|
|
minimum:GETPROP(dict, minimum)
|
|
maximum:GETPROP(dict, maximum)
|
|
maximumFractionDigits:GETPROP(dict, maximumFractionDigits)];
|
|
format.defaultNumericAnswer = GETPROP(dict, defaultNumericAnswer);
|
|
return format;
|
|
},
|
|
(@{
|
|
PROPERTY(style, NSNumber, NSObject, NO,
|
|
^id(id num, __unused ORKESerializationContext *context) { return ORKNumericAnswerStyleToString(((NSNumber *)num).integerValue); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return @(ORKNumericAnswerStyleFromString(string)); }),
|
|
PROPERTY(unit, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(displayUnit, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(minimum, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(maximum, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(maximumFractionDigits, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(defaultNumericAnswer, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(hideUnitWhenAnswerIsEmpty, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(placeholder, NSString, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKScaleAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
NSNumber *defaultValue = (NSNumber *)GETPROP(dict, defaultValue);
|
|
if (defaultValue == nil) {
|
|
defaultValue = [[NSNumber alloc] initWithInt:INT_MAX];
|
|
}
|
|
return [[ORKScaleAnswerFormat alloc] initWithMaximumValue:((NSNumber *)GETPROP(dict, maximum)).integerValue
|
|
minimumValue:((NSNumber *)GETPROP(dict, minimum)).integerValue
|
|
defaultValue:defaultValue.integerValue
|
|
step:((NSNumber *)GETPROP(dict, step)).integerValue
|
|
vertical:((NSNumber *)GETPROP(dict, vertical)).boolValue
|
|
maximumValueDescription:GETPROP(dict, maximumValueDescription)
|
|
minimumValueDescription:GETPROP(dict, minimumValueDescription)];
|
|
},
|
|
(@{
|
|
PROPERTY(minimum, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(maximum, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(defaultValue, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(step, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(vertical, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(maximumValueDescription, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(minimumValueDescription, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(gradientColors, UIColor, NSArray, YES, nil, nil),
|
|
PROPERTY(gradientLocations, NSNumber, NSArray, YES, nil, nil),
|
|
PROPERTY(hideSelectedValue, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(hideRanges, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(hideLabels, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(hideValueMarkers, NSNumber, NSObject, YES, nil, nil),
|
|
IMAGEPROPERTY(minimumImage, NSObject, YES),
|
|
IMAGEPROPERTY(maximumImage, NSObject, YES),
|
|
})),
|
|
ENTRY(ORKContinuousScaleAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
NSNumber *defaultValue = (NSNumber *)GETPROP(dict, defaultValue);
|
|
if (defaultValue == nil) {
|
|
defaultValue = [[NSNumber alloc] initWithDouble:DBL_MAX];
|
|
}
|
|
return [[ORKContinuousScaleAnswerFormat alloc] initWithMaximumValue:((NSNumber *)GETPROP(dict, maximum)).doubleValue
|
|
minimumValue:((NSNumber *)GETPROP(dict, minimum)).doubleValue
|
|
defaultValue:defaultValue.doubleValue
|
|
maximumFractionDigits:((NSNumber *)GETPROP(dict, maximumFractionDigits)).integerValue
|
|
vertical:((NSNumber *)GETPROP(dict, vertical)).boolValue
|
|
maximumValueDescription:GETPROP(dict, maximumValueDescription)
|
|
minimumValueDescription:GETPROP(dict, minimumValueDescription)];
|
|
},
|
|
(@{
|
|
PROPERTY(minimum, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(maximum, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(defaultValue, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(maximumFractionDigits, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(vertical, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(numberStyle, NSNumber, NSObject, YES,
|
|
^id(id numeric, __unused ORKESerializationContext *context) { return tableMapForward(((NSNumber *)numeric).integerValue, numberFormattingStyleTable()); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return @(tableMapReverse(string, numberFormattingStyleTable())); }),
|
|
PROPERTY(maximumValueDescription, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(minimumValueDescription, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(gradientColors, UIColor, NSArray, YES, nil, nil),
|
|
PROPERTY(gradientLocations, NSNumber, NSArray, YES, nil, nil),
|
|
PROPERTY(hideSelectedValue, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(hideRanges, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(hideLabels, NSNumber, NSObject, YES, nil, nil),
|
|
IMAGEPROPERTY(minimumImage, NSObject, YES),
|
|
IMAGEPROPERTY(maximumImage, NSObject, YES),
|
|
})),
|
|
ENTRY(ORKTextScaleAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTextScaleAnswerFormat alloc] initWithTextChoices:GETPROP(dict, textChoices) defaultIndex:(NSInteger)[GETPROP(dict, defaultIndex) doubleValue] vertical:[GETPROP(dict, vertical) boolValue]];
|
|
},
|
|
(@{
|
|
PROPERTY(textChoices, ORKTextChoice, NSArray<ORKTextChoice *>, NO, nil, nil),
|
|
PROPERTY(defaultIndex, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(vertical, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(gradientColors, UIColor, NSArray, YES, nil, nil),
|
|
PROPERTY(gradientLocations, NSNumber, NSArray, YES, nil, nil),
|
|
PROPERTY(hideSelectedValue, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(hideRanges, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(hideLabels, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(hideValueMarkers, NSNumber, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKTextAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTextAnswerFormat alloc] initWithMaximumLength:((NSNumber *)GETPROP(dict, maximumLength)).integerValue];
|
|
},
|
|
(@{
|
|
PROPERTY(maximumLength, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(validationRegularExpression, NSRegularExpression, NSObject, YES,
|
|
^id(id value, __unused ORKESerializationContext *context) { return dictionaryFromRegularExpression((NSRegularExpression *)value); },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return regularExpressionsFromDictionary(dict); } ),
|
|
PROPERTY(invalidMessage, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(defaultTextAnswer, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(autocapitalizationType, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(autocorrectionType, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(spellCheckingType, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(keyboardType, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(multipleLines, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(hideClearButton, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(hideCharacterCountLabel, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(secureTextEntry, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(textContentType, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(passwordRules, UITextInputPasswordRules, NSObject, YES,
|
|
^id(id value, __unused ORKESerializationContext *context) { return dictionaryFromPasswordRules((UITextInputPasswordRules *)value); },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return passwordRulesFromDictionary(dict); } ),
|
|
PROPERTY(placeholder, NSString, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKEmailAnswerFormat,
|
|
nil,
|
|
(@{
|
|
PROPERTY(usernameField, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKConfirmTextAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKConfirmTextAnswerFormat alloc] initWithOriginalItemIdentifier:GETPROP(dict, originalItemIdentifier) errorMessage:GETPROP(dict, errorMessage)];
|
|
},
|
|
(@{
|
|
PROPERTY(originalItemIdentifier, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(errorMessage, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(maximumLength, NSNumber, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKTimeIntervalAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTimeIntervalAnswerFormat alloc] initWithDefaultInterval:((NSNumber *)GETPROP(dict, defaultInterval)).doubleValue step:((NSNumber *)GETPROP(dict, step)).integerValue];
|
|
},
|
|
(@{
|
|
PROPERTY(defaultInterval, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(step, NSNumber, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKBooleanAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKBooleanAnswerFormat alloc] initWithYesString:((NSString *)GETPROP(dict, yes)) noString:((NSString *)GETPROP(dict, no))];
|
|
},
|
|
(@{
|
|
PROPERTY(yes, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(no, NSString, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKHeightAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKHeightAnswerFormat alloc] initWithMeasurementSystem:((NSNumber *)GETPROP(dict, measurementSystem)).integerValue];
|
|
},
|
|
(@{
|
|
PROPERTY(measurementSystem, NSNumber, NSObject, NO,
|
|
^id(id number, __unused ORKESerializationContext *context) { return ORKMeasurementSystemToString(((NSNumber *)number).integerValue); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return @(ORKMeasurementSystemFromString(string)); }),
|
|
})),
|
|
ENTRY(ORKWeightAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKWeightAnswerFormat alloc] initWithMeasurementSystem:((NSNumber *)GETPROP(dict, measurementSystem)).integerValue
|
|
numericPrecision:((NSNumber *)GETPROP(dict, numericPrecision)).integerValue
|
|
minimumValue:((NSNumber *)GETPROP(dict, minimumValue)).doubleValue
|
|
maximumValue:((NSNumber *)GETPROP(dict, maximumValue)).doubleValue
|
|
defaultValue:((NSNumber *)GETPROP(dict, defaultValue)).doubleValue];
|
|
},
|
|
(@{
|
|
PROPERTY(measurementSystem, NSNumber, NSObject, NO,
|
|
^id(id number, __unused ORKESerializationContext *context) { return ORKMeasurementSystemToString(((NSNumber *)number).integerValue); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return @(ORKMeasurementSystemFromString(string)); }),
|
|
PROPERTY(numericPrecision, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(minimumValue, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(maximumValue, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(defaultValue, NSNumber, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKSESAnswerFormat,
|
|
^id(__unused NSDictionary *dict, __unused ORKESerializationPropertyGetter getter) {
|
|
return [[ORKSESAnswerFormat alloc] init];
|
|
},
|
|
(@{
|
|
PROPERTY(topRungText, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(bottomRungText, NSString, NSObject, YES, nil, nil)
|
|
})),
|
|
|
|
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
|
ENTRY(ORKLocationAnswerFormat,
|
|
^id(__unused NSDictionary *dict, __unused ORKESerializationPropertyGetter getter) {
|
|
return [[ORKLocationAnswerFormat alloc] init];
|
|
},
|
|
(@{
|
|
PROPERTY(useCurrentLocation, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(placeholder, NSString, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKLocationRecorderConfiguration,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKLocationRecorderConfiguration alloc] initWithIdentifier:GETPROP(dict,identifier)];
|
|
},
|
|
(@{
|
|
})),
|
|
#endif
|
|
ENTRY(ORKPedometerRecorderConfiguration,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKPedometerRecorderConfiguration alloc] initWithIdentifier:GETPROP(dict,identifier)];
|
|
},
|
|
(@{
|
|
})),
|
|
ENTRY(ORKTouchRecorderConfiguration,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTouchRecorderConfiguration alloc] initWithIdentifier:GETPROP(dict,identifier)];
|
|
},
|
|
(@{
|
|
})),
|
|
ENTRY(ORKResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(identifier, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(startDate, NSDate, NSObject, YES,
|
|
^id(id date, __unused ORKESerializationContext *context) { return ORKEStringFromDateISO8601(date); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return ORKEDateFromStringISO8601(string); }),
|
|
PROPERTY(endDate, NSDate, NSObject, YES,
|
|
^id(id date, __unused ORKESerializationContext *context) { return ORKEStringFromDateISO8601(date); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return ORKEDateFromStringISO8601(string); }),
|
|
PROPERTY(userInfo, NSDictionary, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKTappingSample,
|
|
nil,
|
|
(@{
|
|
PROPERTY(timestamp, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(duration, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(buttonIdentifier, NSNumber, NSObject, NO,
|
|
^id(id numeric, __unused ORKESerializationContext *context) { return tableMapForward(((NSNumber *)numeric).integerValue, buttonIdentifierTable()); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return @(tableMapReverse(string, buttonIdentifierTable())); }),
|
|
PROPERTY(location, NSValue, NSObject, NO,
|
|
^id(id value, __unused ORKESerializationContext *context) { return value?dictionaryFromCGPoint(((NSValue *)value).CGPointValue):nil; },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return [NSValue valueWithCGPoint:pointFromDictionary(dict)]; })
|
|
})),
|
|
ENTRY(ORKTappingIntervalResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(samples, ORKTappingSample, NSArray, NO, nil, nil),
|
|
PROPERTY(stepViewSize, NSValue, NSObject, NO,
|
|
^id(id value, __unused ORKESerializationContext *context) { return value?dictionaryFromCGSize(((NSValue *)value).CGSizeValue):nil; },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return [NSValue valueWithCGSize:sizeFromDictionary(dict)]; }),
|
|
PROPERTY(buttonRect1, NSValue, NSObject, NO,
|
|
^id(id value, __unused ORKESerializationContext *context) { return value?dictionaryFromCGRect(((NSValue *)value).CGRectValue):nil; },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return [NSValue valueWithCGRect:rectFromDictionary(dict)]; }),
|
|
PROPERTY(buttonRect2, NSValue, NSObject, NO,
|
|
^id(id value, __unused ORKESerializationContext *context) { return value?dictionaryFromCGRect(((NSValue *)value).CGRectValue):nil; },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return [NSValue valueWithCGRect:rectFromDictionary(dict)]; })
|
|
})),
|
|
ENTRY(ORKTrailmakingTap,
|
|
nil,
|
|
(@{
|
|
PROPERTY(timestamp, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(index, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(incorrect, NSNumber, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKTrailmakingResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(taps, ORKTrailmakingTap, NSArray, NO, nil, nil),
|
|
PROPERTY(numberOfErrors, NSNumber, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKSpatialSpanMemoryGameTouchSample,
|
|
nil,
|
|
(@{
|
|
PROPERTY(timestamp, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(targetIndex, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(correct, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(location, NSValue, NSObject, NO,
|
|
^id(id value, __unused ORKESerializationContext *context) { return value?dictionaryFromCGPoint(((NSValue *)value).CGPointValue):nil; },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return [NSValue valueWithCGPoint:pointFromDictionary(dict)]; })
|
|
})),
|
|
ENTRY(ORKSpatialSpanMemoryGameRecord,
|
|
nil,
|
|
(@{
|
|
PROPERTY(seed, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(sequence, NSNumber, NSArray, NO, nil, nil),
|
|
PROPERTY(gameSize, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(gameStatus, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(score, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(touchSamples, ORKSpatialSpanMemoryGameTouchSample, NSArray, NO,
|
|
^id(id numeric, __unused ORKESerializationContext *context) { return tableMapForward(((NSNumber *)numeric).integerValue, memoryGameStatusTable()); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return @(tableMapReverse(string, memoryGameStatusTable())); }),
|
|
PROPERTY(targetRects, NSValue, NSArray, NO,
|
|
^id(id value, __unused ORKESerializationContext *context) { return value?dictionaryFromCGRect(((NSValue *)value).CGRectValue):nil; },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return [NSValue valueWithCGRect:rectFromDictionary(dict)]; })
|
|
})),
|
|
ENTRY(ORKSpatialSpanMemoryResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(score, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(numberOfGames, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(numberOfFailures, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(gameRecords, ORKSpatialSpanMemoryGameRecord, NSArray, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKFileResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(contentType, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(fileName, NSString, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKToneAudiometrySample,
|
|
nil,
|
|
(@{
|
|
PROPERTY(frequency, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(channel, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(amplitude, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(channelSelected, NSNumber, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKToneAudiometryResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(outputVolume, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(samples, ORKToneAudiometrySample, NSArray, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKdBHLToneAudiometryUnit,
|
|
nil,
|
|
(@{
|
|
PROPERTY(dBHLValue, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(startOfUnitTimeStamp, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(preStimulusDelay, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(userTapTimeStamp, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(timeoutTimeStamp, NSNumber, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKdBHLToneAudiometryFrequencySample,
|
|
nil,
|
|
(@{
|
|
PROPERTY(frequency, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(calculatedThreshold, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(channel, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(units, ORKdBHLToneAudiometryUnit, NSArray, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKdBHLToneAudiometryResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(outputVolume, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(tonePlaybackDuration, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(postStimulusDelay, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(headphoneType, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(samples, ORKdBHLToneAudiometryFrequencySample, NSArray, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKReactionTimeResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(timestamp, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(fileResult, ORKResult, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKSpeechInNoiseResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(filename, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(targetSentence, NSString, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKSpeechRecognitionResult,
|
|
nil,
|
|
dictionaryForORKSpeechRecognitionResult()),
|
|
ENTRY(ORKStroopResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(startTime, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(endTime, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(color, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(text, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(colorSelected, NSString, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKAccuracyStroopResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(didSelectCorrectColor, NSNumber, NSObject, NO, nil, ^id(__unused id jsonObject, __unused ORKESerializationContext *context) { return @(NO); }),
|
|
PROPERTY(timeTakenToSelect, NSNumber, NSObject, NO, nil, ^id(__unused id jsonObject, __unused ORKESerializationContext *context) { return @(0); }),
|
|
PROPERTY(distanceToClosestCenter, NSNumber, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKTimedWalkResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(distanceInMeters, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(timeLimit, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(duration, NSNumber, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKPSATSample,
|
|
nil,
|
|
(@{
|
|
PROPERTY(correct, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(digit, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(answer, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(time, NSNumber, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKPSATResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(presentationMode, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(interStimulusInterval, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(stimulusDuration, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(length, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(totalCorrect, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(totalDyad, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(totalTime, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(initialDigit, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(samples, ORKPSATSample, NSArray, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKRangeOfMotionResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(start, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(finish, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(minimum, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(maximum, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(range, NSNumber, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKTowerOfHanoiResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(puzzleWasSolved, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(moves, ORKTowerOfHanoiMove, NSArray, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKTowerOfHanoiMove,
|
|
nil,
|
|
(@{
|
|
PROPERTY(timestamp, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(donorTowerIndex, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(recipientTowerIndex, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKHolePegTestSample,
|
|
nil,
|
|
(@{
|
|
PROPERTY(time, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(distance, NSNumber, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKHolePegTestResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(movingDirection, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(dominantHandTested, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(numberOfPegs, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(threshold, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(rotated, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(totalSuccesses, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(totalFailures, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(totalTime, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(totalDistance, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(samples, ORKHolePegTestSample, NSArray, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKPasscodeResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(passcodeSaved, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(touchIdEnabled, NSNumber, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKQuestionResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(questionType, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(noAnswerType, ORKNoAnswer, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKScaleQuestionResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(scaleAnswer, NSNumber, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKChoiceQuestionResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(choiceAnswers, NSObject, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKMultipleComponentQuestionResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(componentsAnswer, NSObject, NSObject, NO, nil, nil),
|
|
PROPERTY(separator, NSString, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKBooleanQuestionResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(booleanAnswer, NSNumber, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKTextQuestionResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(textAnswer, NSString, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKNumericQuestionResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(numericAnswer, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(unit, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(displayUnit, NSString, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKTimeOfDayQuestionResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(dateComponentsAnswer, NSDateComponents, NSObject, NO,
|
|
^id(id dateComponents, __unused ORKESerializationContext *context) { return ORKTimeOfDayStringFromComponents(dateComponents); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return ORKTimeOfDayComponentsFromString(string); })
|
|
})),
|
|
ENTRY(ORKTimeIntervalQuestionResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(intervalAnswer, NSNumber, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKDateQuestionResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(dateAnswer, NSDate, NSObject, NO,
|
|
^id(id date, __unused ORKESerializationContext *context) { return ORKEStringFromDateISO8601(date); },
|
|
^id(id string, __unused ORKESerializationContext *context) { return ORKEDateFromStringISO8601(string); }),
|
|
PROPERTY(calendar, NSCalendar, NSObject, NO,
|
|
^id(id calendar, __unused ORKESerializationContext *context) { return [(NSCalendar *)calendar calendarIdentifier]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [NSCalendar calendarWithIdentifier:string]; }),
|
|
PROPERTY(timeZone, NSTimeZone, NSObject, NO,
|
|
^id(id timeZone, __unused ORKESerializationContext *context) { return @([timeZone secondsFromGMT]); },
|
|
^id(id number, __unused ORKESerializationContext *context) { return [NSTimeZone timeZoneForSecondsFromGMT:(NSInteger)((NSNumber *)number).doubleValue]; })
|
|
})),
|
|
#if ORK_FEATURE_CLLOCATIONMANAGER_AUTHORIZATION
|
|
ENTRY(ORKLocation,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
CLLocationCoordinate2D coordinate = coordinateFromDictionary(dict[@ESTRINGIFY(coordinate)]);
|
|
return [[ORKLocation alloc] initWithCoordinate:coordinate
|
|
region:GETPROP(dict, region)
|
|
userInput:GETPROP(dict, userInput)
|
|
postalAddress:GETPROP(dict, postalAddress)];
|
|
},
|
|
(@{
|
|
PROPERTY(userInput, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(postalAddress, CNPostalAddress, NSObject, NO,
|
|
^id(id value, __unused ORKESerializationContext *context) { return dictionaryFromPostalAddress(value); },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return postalAddressFromDictionary(dict); }),
|
|
PROPERTY(coordinate, NSValue, NSObject, NO,
|
|
^id(id value, __unused ORKESerializationContext *context) { return value ? dictionaryFromCoordinate(((NSValue *)value).MKCoordinateValue) : nil; },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return [NSValue valueWithMKCoordinate:coordinateFromDictionary(dict)]; }),
|
|
PROPERTY(region, CLCircularRegion, NSObject, NO,
|
|
^id(id value, __unused ORKESerializationContext *context) { return dictionaryFromCircularRegion((CLCircularRegion *)value); },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return circularRegionFromDictionary(dict); }),
|
|
})),
|
|
ENTRY(ORKLocationQuestionResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(locationAnswer, ORKLocation, NSObject, NO, nil, nil)
|
|
})),
|
|
#endif
|
|
ENTRY(ORKSESQuestionResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(rungPicked, NSNumber, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKConsentSignatureResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(signature, ORKConsentSignature, NSObject, YES, nil, nil),
|
|
PROPERTY(consented, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKSignatureResult,
|
|
nil,
|
|
(@{
|
|
})),
|
|
ENTRY(ORKCollectionResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(results, ORKResult, NSArray, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKTaskResult,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKTaskResult alloc] initWithTaskIdentifier:GETPROP(dict, identifier) taskRunUUID:GETPROP(dict, taskRunUUID) outputDirectory:nil device:GETPROP(dict, device)];
|
|
},
|
|
(@{
|
|
PROPERTY(taskRunUUID, NSUUID, NSObject, NO,
|
|
^id(id uuid, __unused ORKESerializationContext *context) { return [uuid UUIDString]; },
|
|
^id(id string, __unused ORKESerializationContext *context) { return [[NSUUID alloc] initWithUUIDString:string]; }),
|
|
PROPERTY(device, ORKDevice, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKStepResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(enabledAssistiveTechnology, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(isPreviousResult, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKPageResult,
|
|
nil,
|
|
(@{
|
|
})),
|
|
ENTRY(ORKVideoInstructionStepResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(playbackStoppedTime, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(playbackCompleted, NSNumber, NSObject, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORK3DModelManager,
|
|
^id(__unused NSDictionary *dict, __unused ORKESerializationPropertyGetter getter) {
|
|
return [[ORK3DModelManager alloc] init];
|
|
},
|
|
(@{
|
|
PROPERTY(allowsSelection, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(identifiersOfObjectsToHighlight, NSString, NSArray, YES, nil, nil),
|
|
PROPERTY(highlightColor, UIColor, NSObject, YES,
|
|
^id(id color, __unused ORKESerializationContext *context) { return dictionaryFromColor(color); },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return colorFromDictionary(dict); })
|
|
})),
|
|
ENTRY(ORKUSDZModelManagerResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(identifiersOfSelectedObjects, NSString, NSArray, YES, nil, nil),
|
|
PROPERTY(identifierOfObjectSelectedAtClose, NSString, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKUSDZModelManager,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKUSDZModelManager alloc] initWithUSDZFileName:GETPROP(dict, fileName)];
|
|
},
|
|
(@{
|
|
PROPERTY(enableContinueAfterSelection, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(fileName, NSString, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORK3DModelStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORK3DModelStep alloc] initWithIdentifier:GETPROP(dict, identifier) modelManager:GETPROP(dict, modelManager)];
|
|
},
|
|
(@{
|
|
PROPERTY(modelManager, ORK3DModelManager, NSObject, YES, nil, nil),
|
|
})),
|
|
|
|
ENTRY(ORKFrontFacingCameraStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKFrontFacingCameraStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(maximumRecordingLimit, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(allowsReview, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(allowsRetry, NSNumber, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKFrontFacingCameraStepResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(retryCount, NSNumber, NSObject, NO, nil, nil)
|
|
})),
|
|
ENTRY(ORKAgeAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKAgeAnswerFormat alloc] initWithMinimumAge:((NSNumber *)GETPROP(dict, minimumAge)).integerValue
|
|
maximumAge:((NSNumber *)GETPROP(dict, maximumAge)).integerValue
|
|
minimumAgeCustomText:GETPROP(dict, minimumAgeCustomText)
|
|
maximumAgeCustomText:GETPROP(dict, maximumAgeCustomText)
|
|
showYear:((NSNumber *)GETPROP(dict, showYear)).boolValue
|
|
useYearForResult:((NSNumber *)GETPROP(dict, useYearForResult)).boolValue
|
|
treatMinAgeAsRange:((NSNumber *)GETPROP(dict, treatMinAgeAsRange)).boolValue
|
|
treatMaxAgeAsRange:((NSNumber *)GETPROP(dict, treatMaxAgeAsRange)).boolValue
|
|
defaultValue:((NSNumber *)GETPROP(dict, defaultValue)).integerValue];
|
|
},
|
|
(@{
|
|
PROPERTY(minimumAge, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(maximumAge, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(minimumAgeCustomText, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(maximumAgeCustomText, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(showYear, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(useYearForResult, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(treatMinAgeAsRange, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(treatMaxAgeAsRange, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(relativeYear, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(defaultValue, NSNumber, NSObject, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKColorChoiceAnswerFormat,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKColorChoiceAnswerFormat alloc] initWithStyle:((NSNumber *)GETPROP(dict, style)).integerValue colorChoices:GETPROP(dict, colorChoices)];
|
|
},
|
|
(@{
|
|
PROPERTY(style, NSNumber, NSObject, NO, NUMTOSTRINGBLOCK(ORKChoiceAnswerStyleTable()), STRINGTONUMBLOCK(ORKChoiceAnswerStyleTable())),
|
|
PROPERTY(colorChoices, ORKColorChoice, NSArray, NO, nil, nil),
|
|
})),
|
|
ENTRY(ORKColorChoice,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKColorChoice alloc] initWithColor:GETPROP(dict, color)
|
|
text:GETPROP(dict, text)
|
|
detailText:GETPROP(dict, detailText)
|
|
value:GETPROP(dict, value)
|
|
exclusive:((NSNumber *)GETPROP(dict, exclusive)).boolValue];
|
|
},
|
|
(@{
|
|
PROPERTY(text, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(detailText, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(value, NSObject, NSObject, NO, nil, nil),
|
|
PROPERTY(exclusive, NSNumber, NSObject, NO, nil, nil),
|
|
PROPERTY(color, UIColor, NSObject, YES,
|
|
^id(id color, __unused ORKESerializationContext *context) { return dictionaryFromColor(color); },
|
|
^id(id dict, __unused ORKESerializationContext *context) { return colorFromDictionary(dict); })
|
|
})),
|
|
ENTRY(ORKRelativeGroup,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKRelativeGroup alloc] initWithIdentifier:GETPROP(dict, identifier)
|
|
name:GETPROP(dict, name)
|
|
sectionTitle:GETPROP(dict, sectionTitle)
|
|
sectionDetailText:GETPROP(dict, sectionDetailText)
|
|
identifierForCellTitle:GETPROP(dict, identifierForCellTitle)
|
|
maxAllowed:[GETPROP(dict, maxAllowed) unsignedIntegerValue]
|
|
formSteps:GETPROP(dict, formSteps)
|
|
detailTextIdentifiers:GETPROP(dict, detailTextIdentifiers)];
|
|
},
|
|
(@{
|
|
PROPERTY(identifier, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(name, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(sectionTitle, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(sectionDetailText, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(identifierForCellTitle, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(maxAllowed, NSNumber, NSObject, YES, nil, nil),
|
|
PROPERTY(formSteps, ORKFormStep, NSArray, YES, nil, nil),
|
|
PROPERTY(detailTextIdentifiers, NSString, NSArray, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKHealthCondition,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKHealthCondition alloc] initWithIdentifier:GETPROP(dict, identifier) displayName:GETPROP(dict, displayName) value:GETPROP(dict, value)];
|
|
},
|
|
(@{
|
|
PROPERTY(identifier, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(displayName, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(value, NSObject, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKRelatedPerson,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKRelatedPerson alloc] initWithIdentifier:GETPROP(dict, identifier) groupIdentifier:GETPROP(dict, groupIdentifier) identifierForCellTitle:GETPROP(dict, identifierForCellTitle) taskResult:GETPROP(dict, taskResult)];
|
|
},
|
|
(@{
|
|
PROPERTY(identifier, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(groupIdentifier, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(identifierForCellTitle, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(taskResult, ORKTaskResult, NSObject, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKFamilyHistoryResult,
|
|
nil,
|
|
(@{
|
|
PROPERTY(relatedPersons, ORKRelatedPerson, NSArray, YES, nil, nil),
|
|
PROPERTY(displayedConditions, NSString, NSArray, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKConditionStepConfiguration,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKConditionStepConfiguration alloc] initWithStepIdentifier:GETPROP(dict, stepIdentifier) conditionsFormItemIdentifier:GETPROP(dict, conditionsFormItemIdentifier) conditions:GETPROP(dict, conditions) formItems:GETPROP(dict, formItems)];
|
|
},
|
|
(@{
|
|
PROPERTY(stepIdentifier, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(conditionsFormItemIdentifier, NSString, NSObject, YES, nil, nil),
|
|
PROPERTY(conditions, ORKHealthCondition, NSArray, YES, nil, nil),
|
|
PROPERTY(formItems, ORKFormItem, NSArray, YES, nil, nil)
|
|
})),
|
|
ENTRY(ORKFamilyHistoryStep,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKFamilyHistoryStep alloc] initWithIdentifier:GETPROP(dict, identifier)];
|
|
},
|
|
(@{
|
|
PROPERTY(conditionStepConfiguration, ORKConditionStepConfiguration, NSObject, YES, nil, nil),
|
|
PROPERTY(relativeGroups, ORKRelativeGroup, NSArray, YES, nil, nil),
|
|
})),
|
|
ENTRY(ORKDevice, ^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKDevice alloc] initWithProduct:GETPROP(dict, product)
|
|
osVersion:GETPROP(dict, osVersion)
|
|
osBuild:GETPROP(dict, osBuild)
|
|
platform:GETPROP(dict, platform)];},
|
|
(@{
|
|
PROPERTY(product, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(osVersion, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(osBuild, NSString, NSObject, NO, nil, nil),
|
|
PROPERTY(platform, NSString, NSObject, NO, nil, nil)
|
|
})),
|
|
} mutableCopy];
|
|
if (@available(iOS 12.0, *)) {
|
|
[internalEncodingTable addEntriesFromDictionary:@{ ENTRY(ORKHealthClinicalTypeRecorderConfiguration,
|
|
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
|
|
return [[ORKHealthClinicalTypeRecorderConfiguration alloc] initWithIdentifier:GETPROP(dict, identifier) healthClinicalType:GETPROP(dict, healthClinicalType) healthFHIRResourceType:GETPROP(dict, healthFHIRResourceType)];
|
|
},
|
|
(@{
|
|
PROPERTY(healthClinicalType, HKClinicalType, NSObject, NO,
|
|
^id(id type, __unused ORKESerializationContext *context) { return identifierFromClinicalType(type); },
|
|
^id(id identifier, __unused ORKESerializationContext *context) { return typeFromIdentifier(identifier); }),
|
|
PROPERTY(healthFHIRResourceType, NSString, NSObject, NO, nil, nil),
|
|
})) }];
|
|
}
|
|
});
|
|
return internalEncodingTable;
|
|
}
|
|
#undef GETPROP
|
|
|
|
static NSArray<ORKESerializableTableEntry *> *classEncodingsForClass(Class class) {
|
|
NSDictionary<NSString *, ORKESerializableTableEntry *> *encodingTable = ORKESerializationEncodingTable();
|
|
|
|
NSMutableArray<ORKESerializableTableEntry *> *classEncodings = [NSMutableArray array];
|
|
Class currentClass = class;
|
|
while (currentClass != nil) {
|
|
NSString *className = NSStringFromClass(currentClass);
|
|
ORKESerializableTableEntry *classEncoding = encodingTable[className];
|
|
if (classEncoding) {
|
|
[classEncodings addObject:classEncoding];
|
|
}
|
|
currentClass = [currentClass superclass];
|
|
}
|
|
return [classEncodings copy];
|
|
}
|
|
|
|
static id objectForJsonObject(id input,
|
|
Class expectedClass,
|
|
ORKESerializationJSONToObjectBlock converterBlock,
|
|
ORKESerializationContext *context) {
|
|
id output = nil;
|
|
|
|
if (converterBlock != nil) {
|
|
input = converterBlock(input, context);
|
|
if (input == nil) {
|
|
// Object converted to nothing
|
|
return nil;
|
|
}
|
|
}
|
|
|
|
id<ORKESerializationLocalizer> localizer = context.localizer;
|
|
id<ORKESerializationStringInterpolator> stringInterpolator = context.stringInterpolator;
|
|
|
|
|
|
if (expectedClass != nil && [input isKindOfClass:expectedClass]) {
|
|
// Input is already of the expected class, do nothing
|
|
output = input;
|
|
} else if ([input isKindOfClass:[NSDictionary class]]) {
|
|
NSDictionary *dict = (NSDictionary *)input;
|
|
NSString *className = input[_ClassKey]; // todo: might be a spot to convert class
|
|
|
|
|
|
ORKESerializationPropertyInjector *propertyInjector = context.propertyInjector;
|
|
if (propertyInjector != nil) {
|
|
NSDictionary *dictionary = (NSDictionary *)input;
|
|
dict = [propertyInjector injectedDictionaryWithDictionary:dictionary];
|
|
}
|
|
|
|
if (expectedClass != nil) {
|
|
NSCAssert([NSClassFromString(className) isSubclassOfClass:expectedClass], @"Expected subclass of %@ but got %@", expectedClass, className);
|
|
}
|
|
NSArray *classEncodings = classEncodingsForClass(NSClassFromString(className));
|
|
NSCAssert([classEncodings count] > 0, @"Expected serializable class but got %@", className);
|
|
|
|
ORKESerializableTableEntry *leafClassEncoding = classEncodings.firstObject;
|
|
ORKESerializationInitBlock initBlock = leafClassEncoding.initBlock;
|
|
BOOL writeAllProperties = YES;
|
|
if (initBlock != nil) {
|
|
output = initBlock(dict,
|
|
^id(NSDictionary *propDict, NSString *param) {
|
|
return propFromDict(propDict, param, context); });
|
|
writeAllProperties = NO;
|
|
} else {
|
|
Class class = NSClassFromString(className);
|
|
output = [[class alloc] init];
|
|
}
|
|
|
|
for (NSString *key in [dict allKeys]) {
|
|
if ([key isEqualToString:_ClassKey]) {
|
|
continue;
|
|
}
|
|
|
|
BOOL haveSetProp = NO;
|
|
for (ORKESerializableTableEntry *encoding in classEncodings) {
|
|
NSDictionary *propertyTable = encoding.properties;
|
|
ORKESerializableProperty *propertyEntry = propertyTable[key];
|
|
if (propertyEntry != nil) {
|
|
// Only write the property if it has not already been set during init
|
|
if (writeAllProperties || propertyEntry.writeAfterInit) {
|
|
id property = propFromDict(dict, key, context);
|
|
if ([property isKindOfClass: [NSString class]] && ![key isEqualToString:@"identifier"]) {
|
|
if (localizer != nil) {
|
|
property = [localizer localizedStringForKey:property];
|
|
}
|
|
|
|
if (stringInterpolator != nil) {
|
|
property = [stringInterpolator interpolatedStringForString:property];
|
|
}
|
|
}
|
|
[output setValue:property forKey:key];
|
|
}
|
|
haveSetProp = YES;
|
|
break;
|
|
}
|
|
}
|
|
NSCAssert(haveSetProp, @"Unexpected property on %@: %@", className, key);
|
|
}
|
|
} else {
|
|
NSCAssert(0, @"Unexpected input of class %@ for %@", [input class], expectedClass);
|
|
}
|
|
return output;
|
|
}
|
|
|
|
static BOOL isValid(id object) {
|
|
return [NSJSONSerialization isValidJSONObject:object] || [object isKindOfClass:[NSNumber class]] || [object isKindOfClass:[NSString class]] || [object isKindOfClass:[NSNull class]] || [object isKindOfClass:[ORKNoAnswer class]];
|
|
}
|
|
|
|
static id jsonObjectForObject(id object, ORKESerializationContext *context) {
|
|
if (object == nil) {
|
|
// Leaf: nil
|
|
return nil;
|
|
}
|
|
|
|
id jsonOutput = nil;
|
|
Class c = [object class];
|
|
|
|
NSArray *classEncodings = classEncodingsForClass(c);
|
|
|
|
if ([classEncodings count]) {
|
|
NSMutableDictionary *encodedDict = [NSMutableDictionary dictionary];
|
|
encodedDict[_ClassKey] = NSStringFromClass(c);
|
|
|
|
NSMutableSet<NSString *> *excludedPoperties = [NSMutableSet set];
|
|
for (ORKESerializableTableEntry *encoding in classEncodings) {
|
|
NSDictionary<NSString *, ORKESerializableProperty *> *propertyTable = encoding.properties;
|
|
for (NSString *propertyName in [propertyTable allKeys]) {
|
|
ORKESerializableProperty *propertyEntry = propertyTable[propertyName];
|
|
if (propertyEntry.skipSerialization) {
|
|
[excludedPoperties addObject:propertyEntry.propertyName];
|
|
continue;
|
|
}
|
|
if ([excludedPoperties containsObject:propertyEntry.propertyName]) {
|
|
continue;
|
|
}
|
|
ORKESerializationObjectToJSONBlock converter = propertyEntry.objectToJSONBlock;
|
|
Class containerClass = propertyEntry.containerClass;
|
|
id valueForKey = [object valueForKey:propertyName];
|
|
if (valueForKey != nil) {
|
|
if ([containerClass isSubclassOfClass:[NSArray class]]) {
|
|
NSMutableArray *a = [NSMutableArray array];
|
|
for (id valueItem in valueForKey) {
|
|
id outputItem;
|
|
if (converter != nil) {
|
|
outputItem = converter(valueItem, context);
|
|
NSCAssert(isValid(valueItem), @"Expected valid JSON object");
|
|
} else {
|
|
// Recurse for each property
|
|
outputItem = jsonObjectForObject(valueItem, context);
|
|
}
|
|
[a addObject:outputItem];
|
|
}
|
|
valueForKey = a;
|
|
} else {
|
|
if (converter != nil) {
|
|
valueForKey = converter(valueForKey, context);
|
|
NSCAssert((valueForKey == nil) || isValid(valueForKey), @"Expected valid JSON object");
|
|
} else {
|
|
// Recurse for each property
|
|
valueForKey = jsonObjectForObject(valueForKey, context);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (valueForKey != nil) {
|
|
encodedDict[propertyName] = valueForKey;
|
|
}
|
|
}
|
|
}
|
|
|
|
jsonOutput = encodedDict;
|
|
} else if ([c isSubclassOfClass:[NSArray class]]) {
|
|
NSArray *inputArray = (NSArray *)object;
|
|
NSMutableArray *encodedArray = [NSMutableArray arrayWithCapacity:[inputArray count]];
|
|
for (id input in inputArray) {
|
|
// Recurse for each array element
|
|
[encodedArray addObject:jsonObjectForObject(input, context)];
|
|
}
|
|
jsonOutput = encodedArray;
|
|
} else if ([c isSubclassOfClass:[NSDictionary class]]) {
|
|
NSDictionary *inputDict = (NSDictionary *)object;
|
|
NSMutableDictionary *encodedDictionary = [NSMutableDictionary dictionaryWithCapacity:[inputDict count]];
|
|
for (NSString *key in [inputDict allKeys] ) {
|
|
// Recurse for each dictionary value
|
|
encodedDictionary[key] = jsonObjectForObject(inputDict[key], context);
|
|
}
|
|
jsonOutput = encodedDictionary;
|
|
} else if (![c isSubclassOfClass:[NSPredicate class]]) { // Ignore NSPredicate which cannot be easily serialized for now
|
|
NSCAssert(isValid(object), @"Expected valid JSON object");
|
|
// Leaf: native JSON object
|
|
jsonOutput = object;
|
|
}
|
|
|
|
return jsonOutput;
|
|
}
|
|
|
|
+ (NSDictionary *)JSONObjectForObject:(id)object error:(__unused NSError * __autoreleasing *)error {
|
|
return [self JSONObjectForObject:object context:[[ORKESerializationContext alloc] initWithLocalizer:nil imageProvider:nil stringInterpolator:nil propertyInjector:nil] error:error];
|
|
}
|
|
|
|
+ (NSDictionary *)JSONObjectForObject:(id)object context:(ORKESerializationContext *)context error:(__unused NSError * __autoreleasing *)error {
|
|
id json = jsonObjectForObject(object, context);
|
|
return json;
|
|
}
|
|
|
|
+ (id)objectFromJSONObject:(NSDictionary *)object error:(__unused NSError * __autoreleasing *)error {
|
|
return objectForJsonObject(object, nil, nil, [[ORKESerializationContext alloc] initWithLocalizer:nil imageProvider:nil stringInterpolator:nil propertyInjector:nil]);
|
|
}
|
|
|
|
+ (id)objectFromJSONObject:(NSDictionary *)object context:(ORKESerializationContext *)context error:(__unused NSError * __autoreleasing *)error {
|
|
return objectForJsonObject(object, nil, nil, context);
|
|
}
|
|
|
|
+ (NSData *)JSONDataForObject:(id)object error:(NSError * __autoreleasing *)error {
|
|
id json = jsonObjectForObject(object, [[ORKESerializationContext alloc] initWithLocalizer:nil imageProvider:nil stringInterpolator:nil propertyInjector:nil]);
|
|
return [NSJSONSerialization dataWithJSONObject:json options:NSJSONWritingSortedKeys error:error];
|
|
}
|
|
|
|
+ (id)objectFromJSONData:(NSData *)data error:(NSError * __autoreleasing *)error {
|
|
id json = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingOptions)0 error:error];
|
|
id ret = nil;
|
|
if (json != nil) {
|
|
ret = objectForJsonObject(json, nil, nil, [[ORKESerializationContext alloc] initWithLocalizer:nil imageProvider:nil stringInterpolator:nil propertyInjector:nil]);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
+ (NSArray *)serializableClasses {
|
|
NSMutableArray *a = [NSMutableArray array];
|
|
NSDictionary *table = ORKESerializationEncodingTable();
|
|
for (NSString *key in [table allKeys]) {
|
|
[a addObject:NSClassFromString(key)];
|
|
}
|
|
return a;
|
|
}
|
|
|
|
|
|
+ (NSArray<NSString *> *)serializedPropertiesForClass:(Class)c {
|
|
NSArray<ORKESerializableTableEntry *> *entries = classEncodingsForClass(c);
|
|
NSMutableArray *properties = [NSMutableArray array];
|
|
for (ORKESerializableTableEntry *entry in entries) {
|
|
[properties addObjectsFromArray:[entry.properties allKeys]];
|
|
}
|
|
return properties;
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
@implementation ORKESerializer(Registration)
|
|
|
|
+ (void)registerSerializableClass:(Class)serializableClass
|
|
initBlock:(ORKESerializationInitBlock)initBlock {
|
|
NSMutableDictionary *encodingTable = ORKESerializationEncodingTable();
|
|
|
|
ORKESerializableTableEntry *entry = encodingTable[NSStringFromClass(serializableClass)];
|
|
if (entry) {
|
|
entry.class = serializableClass;
|
|
entry.initBlock = initBlock;
|
|
} else {
|
|
entry = [[ORKESerializableTableEntry alloc] initWithClass:serializableClass initBlock:initBlock properties:@{}];
|
|
encodingTable[NSStringFromClass(serializableClass)] = entry;
|
|
}
|
|
}
|
|
|
|
+ (void)registerSerializableClassPropertyName:(NSString *)propertyName
|
|
forClass:(Class)serializableClass
|
|
valueClass:(Class)valueClass
|
|
containerClass:(Class)containerClass
|
|
writeAfterInit:(BOOL)writeAfterInit
|
|
objectToJSONBlock:(ORKESerializationObjectToJSONBlock)objectToJSON
|
|
jsonToObjectBlock:(ORKESerializationJSONToObjectBlock)jsonToObjectBlock
|
|
skipSerialization:(BOOL)skipSerialization {
|
|
NSMutableDictionary *encodingTable = ORKESerializationEncodingTable();
|
|
|
|
ORKESerializableTableEntry *entry = encodingTable[NSStringFromClass(serializableClass)];
|
|
if (!entry) {
|
|
entry = [[ORKESerializableTableEntry alloc] initWithClass:serializableClass initBlock:nil properties:@{}];
|
|
encodingTable[NSStringFromClass(serializableClass)] = entry;
|
|
}
|
|
|
|
ORKESerializableProperty *property = entry.properties[propertyName];
|
|
if (property == nil) {
|
|
property = [[ORKESerializableProperty alloc] initWithPropertyName:propertyName
|
|
valueClass:valueClass
|
|
containerClass:containerClass
|
|
writeAfterInit:writeAfterInit
|
|
objectToJSONBlock:objectToJSON
|
|
jsonToObjectBlock:jsonToObjectBlock
|
|
skipSerialization:skipSerialization];
|
|
entry.properties[propertyName] = property;
|
|
} else {
|
|
property.propertyName = propertyName;
|
|
property.valueClass = valueClass;
|
|
property.containerClass = containerClass;
|
|
property.writeAfterInit = writeAfterInit;
|
|
property.objectToJSONBlock = objectToJSON;
|
|
property.jsonToObjectBlock = jsonToObjectBlock;
|
|
property.skipSerialization = skipSerialization;
|
|
}
|
|
}
|
|
|
|
@end
|