Skip to content

Commit

Permalink
Merge pull request ResearchKit#115 from dephillipsmichael/feature/BRI…
Browse files Browse the repository at this point in the history
…DGE-1054

feature/BRIDGE-1054
  • Loading branch information
syoung-smallwisdom committed Mar 29, 2016
2 parents 068723b + 69df730 commit 7751935
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
static NSString * const kStartDateKey = @"startDate";
static NSString * const kEndDateKey = @"endDate";
static NSString * const kUserInfoKey = @"userInfo";
static NSString * const kAnswerKey = @"answer";

//
// General-Use Dictionary Keys
Expand Down Expand Up @@ -376,8 +377,17 @@ - (BOOL)appendArchive:(APCDataArchive *)archive withQuestionResult: (ORKQuestion
}
}

// Almost all of the time we want dates to be serialized as ISO 8601 per sage bridge request
// However, in the instance of question result with ORKQuestionTypeDate type, we want to use
// a specific date format per sage bridge documentation
NSDictionary* dateFormatterForKeys = nil;
if (result.questionType == ORKQuestionTypeDate) {
dateFormatterForKeys = @{ kAnswerKey: ORKResultDateFormatter() };
}

NSDictionary *propertiesToSave = [result dictionaryWithValuesForKeys: propertyNames];
NSDictionary *serializableDictionary = [APCJSONSerializer serializableDictionaryFromSourceDictionary: propertiesToSave];
APCJSONSerializer* jsonSerializer = [[APCJSONSerializer alloc] initWithDateFormatterForKeys:dateFormatterForKeys];
NSDictionary *serializableDictionary = [jsonSerializer serializableDictionaryFromSourceDictionary:propertiesToSave];

APCLogDebug(@"%@", serializableDictionary);

Expand Down
18 changes: 18 additions & 0 deletions APCAppCore/APCAppCore/Library/Objects/APCJSONSerializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,17 @@ FOUNDATION_EXPORT NSString * const kAPCSerializedDataKey_FileInfoContentType;
*/
@interface APCJSONSerializer : NSObject

/**
@param This gives the caller a chance to make certain keys be serialized in a dictionary with
a custom date formatter applied to them.
For example, in ORKQuestionResult, the "answer" key needs formatted to "MM-DD-YYYY"
The dictionary would be:
@{ @"answer" : NSDateformatter("MM-DD-YYYY") };
*/
- (instancetype) initWithDateFormatterForKeys: (NSDictionary*) dateFormatterForKeys;

/**
Converts a dictionary, and all its contents, into data we
can serialize into JSON using NSJSONSerializer. Does its
Expand All @@ -109,6 +120,13 @@ FOUNDATION_EXPORT NSString * const kAPCSerializedDataKey_FileInfoContentType;
object and its contents as it uses when serializing the top-
level objects.
*/
- (NSDictionary *) serializableDictionaryFromSourceDictionary: (NSDictionary *) sourceDictionary;

/*
Class helper method with same functionality as one above
Use if you need to just serialize a dictionary and do not need
to use the date formatter keys property
*/
+ (NSDictionary *) serializableDictionaryFromSourceDictionary: (NSDictionary *) sourceDictionary;

@end
67 changes: 55 additions & 12 deletions APCAppCore/APCAppCore/Library/Objects/APCJSONSerializer.m
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,49 @@
"[a-fA-F0-9]{4}\\-"
"[a-fA-F0-9]{4}\\-"
"[a-fA-F0-9]{12}");
@interface APCJSONSerializer ()

/**
This will be set by the method serializableDictionaryFromSourceDictionary
And used to see if certain keys being serialized in a dictionary need
a custom date formatter applied to them.
For example, in ORKQuestionResult, the "answer" key needs formatted to "MM-DD-YYYY"
So the dictionary would be @{ @"answer" : NSDateformatter("MM-DD-YYYY") };
*/
@property (nonatomic, strong) NSDictionary* dateFormattersForKeys;
/**
This is the custom date formatter that will be used, per sDateFormattersForKeys value
*/
@property (nonatomic, strong) NSDateFormatter* customDateFormatter;

@end

@implementation APCJSONSerializer

- (instancetype) initWithDateFormatterForKeys: (NSDictionary*) dateFormatterForKeys
{
if (self = [super init])
{
_dateFormattersForKeys = dateFormatterForKeys;
}
return self;
}

- (NSDictionary *) serializableDictionaryFromSourceDictionary: (NSDictionary *) sourceDictionary
{
NSDictionary *result = [self serializableDictionaryFromSourceDictionary: sourceDictionary
atRecursionDepth: 0];
return result;
}

/**
The public API. See comments in the header file.
*/
+ (NSDictionary *) serializableDictionaryFromSourceDictionary: (NSDictionary *) sourceDictionary
{
NSDictionary *result = [self serializableDictionaryFromSourceDictionary: sourceDictionary
atRecursionDepth: 0];

APCJSONSerializer* instance = [APCJSONSerializer new];
NSDictionary *result = [instance serializableDictionaryFromSourceDictionary: sourceDictionary
atRecursionDepth: 0];
return result;
}

Expand All @@ -105,7 +136,7 @@ + (NSDictionary *) serializableDictionaryFromSourceDictionary: (NSDictionary *)
pass in -- e.g., NSDates get converted to a precisely-formatted
NSString.
*/
+ (id) serializableObjectFromSourceObject: (id) sourceObject
- (id) serializableObjectFromSourceObject: (id) sourceObject
atRecursionDepth: (NSUInteger) recursionDepth
{
id result = nil;
Expand All @@ -130,7 +161,7 @@ + (id) serializableObjectFromSourceObject: (id) sourceObject
return result;
}

+ (NSArray *) serializableArrayFromSourceArray: (NSArray *) sourceArray
- (NSArray *) serializableArrayFromSourceArray: (NSArray *) sourceArray
atRecursionDepth: (NSUInteger) recursionDepth
{
NSMutableArray *resultArray = [NSMutableArray new];
Expand All @@ -149,7 +180,7 @@ + (NSArray *) serializableArrayFromSourceArray: (NSArray *) sourceArray
return resultArray;
}

+ (NSDictionary *) serializableDictionaryFromSourceDictionary: (NSDictionary *) sourceDictionary
- (NSDictionary *) serializableDictionaryFromSourceDictionary: (NSDictionary *) sourceDictionary
atRecursionDepth: (NSUInteger) recursionDepth
{
NSMutableDictionary *resultDictionary = [NSMutableDictionary new];
Expand Down Expand Up @@ -210,11 +241,19 @@ + (NSDictionary *) serializableDictionaryFromSourceDictionary: (NSDictionary *)
{
// "else" nothing. This applies to every other decision.
}


// We only want to apply the special date formatter for keys specified in sDateFormattersForKeys
NSDateFormatter* oldCustomDateFormatter = self.customDateFormatter;
id customDateFormatter = self.dateFormattersForKeys[key];
if (customDateFormatter != nil && [customDateFormatter isKindOfClass:[NSDateFormatter class]]) {
self.customDateFormatter = customDateFormatter;
}

convertedValue = [self serializableObjectFromSourceObject: value
atRecursionDepth: recursionDepth + 1];


self.customDateFormatter = oldCustomDateFormatter;

if (convertedValue != nil)
{
resultDictionary [convertedKey] = convertedValue;
Expand All @@ -229,7 +268,7 @@ + (NSDictionary *) serializableDictionaryFromSourceDictionary: (NSDictionary *)
A "simple object" is anything that's not an NSDictionary or an
NSArray.
*/
+ (id) serializableSimpleObjectFromSourceSimpleObject: (id) sourceObject
- (id) serializableSimpleObjectFromSourceSimpleObject: (id) sourceObject
{
id result = nil;

Expand All @@ -253,6 +292,10 @@ + (id) serializableSimpleObjectFromSourceSimpleObject: (id) sourceObject
{
NSDate *theDate = (NSDate *) sourceObject;
NSString *sageFriendlyDate = theDate.toStringInISO8601Format;
// In some instances, we need to override the date formatting
if (self.customDateFormatter != nil) {
sageFriendlyDate = [self.customDateFormatter stringFromDate:theDate];
}
result = sageFriendlyDate;
}

Expand Down Expand Up @@ -347,7 +390,7 @@ + (id) serializableSimpleObjectFromSourceSimpleObject: (id) sourceObject
Try to convert the specified item to an NSNumber, specifically
if it's a String that looks like a Boolean or an intenger.
*/
+ (NSNumber *) extractIntOrBoolFromString: (NSString *) itemAsString
- (NSNumber *) extractIntOrBoolFromString: (NSString *) itemAsString
{
NSNumber *result = nil;

Expand Down Expand Up @@ -392,7 +435,7 @@ + (NSNumber *) extractIntOrBoolFromString: (NSString *) itemAsString
/**
Try to convert the specified Number to an RKQuestionType.
*/
+ (NSNumber *) extractRKQuestionTypeFromNSNumber: (NSNumber *) item
- (NSNumber *) extractRKQuestionTypeFromNSNumber: (NSNumber *) item
{
NSNumber* result = nil;

Expand Down Expand Up @@ -427,7 +470,7 @@ Which means (I guess) that Apple reserves the right to
Details:
https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSJSONSerialization_Class/
*/
+ (id) safeSerializableItemFromItem: (id) item
- (id) safeSerializableItemFromItem: (id) item
{
id result = nil;

Expand Down

0 comments on commit 7751935

Please sign in to comment.