diff --git a/CSMapperTestApp/CSMapperTestApp.xcodeproj/project.xcworkspace/xcshareddata/CSMapperTestApp.xccheckout b/CSMapperTestApp/CSMapperTestApp.xcodeproj/project.xcworkspace/xcshareddata/CSMapperTestApp.xccheckout
index a09fd2a..f601a31 100644
--- a/CSMapperTestApp/CSMapperTestApp.xcodeproj/project.xcworkspace/xcshareddata/CSMapperTestApp.xccheckout
+++ b/CSMapperTestApp/CSMapperTestApp.xcodeproj/project.xcworkspace/xcshareddata/CSMapperTestApp.xccheckout
@@ -10,29 +10,29 @@
CSMapperTestApp
IDESourceControlProjectOriginsDictionary
- 58B62EAD-450F-433B-9448-4E0A05497FBF
- ssh://github.com/marcammann/CSMapper.git
+ 7B4F58B70F1D66ED172BF588CBF60BF38A1FA730
+ github.com:AntonTheDev/CSMapper.git
IDESourceControlProjectPath
- CSMapperTestApp/CSMapperTestApp.xcodeproj/project.xcworkspace
+ CSMapperTestApp/CSMapperTestApp.xcodeproj
IDESourceControlProjectRelativeInstallPathDictionary
- 58B62EAD-450F-433B-9448-4E0A05497FBF
+ 7B4F58B70F1D66ED172BF588CBF60BF38A1FA730
../../..
IDESourceControlProjectURL
- ssh://github.com/marcammann/CSMapper.git
+ github.com:AntonTheDev/CSMapper.git
IDESourceControlProjectVersion
- 110
+ 111
IDESourceControlProjectWCCIdentifier
- 58B62EAD-450F-433B-9448-4E0A05497FBF
+ 7B4F58B70F1D66ED172BF588CBF60BF38A1FA730
IDESourceControlProjectWCConfigurations
IDESourceControlRepositoryExtensionIdentifierKey
public.vcs.git
IDESourceControlWCCIdentifierKey
- 58B62EAD-450F-433B-9448-4E0A05497FBF
+ 7B4F58B70F1D66ED172BF588CBF60BF38A1FA730
IDESourceControlWCCName
CSMapper
diff --git a/Classes/NSObject+CSAPI.m b/Classes/NSObject+CSAPI.m
index ad67e19..42a3d75 100644
--- a/Classes/NSObject+CSAPI.m
+++ b/Classes/NSObject+CSAPI.m
@@ -20,6 +20,7 @@
static NSString * const CSMappingClassKey = @"type";
static NSString * const CSMappingGroupsKey = @"groups";
static NSString * const CSMappingArraySubTypeKey = @"array_subtype";
+static NSString * const CSMappingCollectionSubTypeKey = @"collection_subtype";
static NSString * const CSMappingMapperKey = @"mapper";
static NSString * const CSMappingDefaultKey = @"default";
@@ -155,7 +156,7 @@ - (void)mapAttributesWithDictionary:(NSDictionary *)aDictionary groups:(NSArray
selector = NSSelectorFromString([NSString stringWithFormat:@"%@Value", forcedClass]);
if ([inputValue respondsToSelector:selector]) {
// Try to use the built in conversion features for known types
- outputValue = objc_msgSend(inputValue, selector);
+ outputValue = ((id (*)(id, SEL))objc_msgSend)(inputValue, selector);
} else {
// Try to map unknown type with same technique.
id newValue = [[forcedClass alloc] init];
@@ -165,26 +166,46 @@ - (void)mapAttributesWithDictionary:(NSDictionary *)aDictionary groups:(NSArray
}
//check to see if there is a type for the objects in an array
- arraySubTypeValue = [propertyMapping objectForKey:CSMappingArraySubTypeKey];
-
- if ([inputValue isKindOfClass:[NSArray class]] && arraySubTypeValue) {
+ arraySubTypeValue = [propertyMapping objectForKey:CSMappingCollectionSubTypeKey];
+
+ if(!arraySubTypeValue)
+ {
+ // Backwards compatibility prior to the addition of dictionary type mapping
+ arraySubTypeValue = [propertyMapping objectForKey:CSMappingArraySubTypeKey];
+ }
+
+ if (arraySubTypeValue) {
forcedClassString = arraySubTypeValue;
forcedClass = NSClassFromString(arraySubTypeValue);
NSMutableArray *newSubObjectArray = [NSMutableArray new];
-
- for (id subobjectDict in inputValue) {
- id newValue = [[forcedClass alloc] init];
- [newValue mapAttributesWithDictionary:subobjectDict];
- [newSubObjectArray addObject:newValue];
+
+ if ([inputValue isKindOfClass:[NSArray class]] ){
+ for (id subobjectDict in inputValue) {
+ id newValue = [[forcedClass alloc] init];
+ [newValue mapAttributesWithDictionary:subobjectDict];
+ [newSubObjectArray addObject:newValue];
+ }
+ } else if ([inputValue isKindOfClass:[NSDictionary class]] ){
+ for (id subobjectDict in [inputValue allValues]) {
+ id newValue = [[forcedClass alloc] init];
+ [newValue mapAttributesWithDictionary:subobjectDict];
+ [newSubObjectArray addObject:newValue];
+ }
}
+
outputValue = newSubObjectArray;
}
-
+
if (mapperClass && mapperClass) {
outputValue = [(id)mapperClass transformValue:inputValue];
}
+ if([propertyName isEqualToString:@"subDictionaryValue"])
+ {
+ NSLog(@"STOP");
+ }
+
[self setValue:outputValue forKey:propertyName];
}
}
@@ -251,12 +272,10 @@ - (NSNumber *)NSNumberValue {
return (NSNumber *)self;
} else {
-
return nil;
}
}
-
/**
Converts an object into an NSString
*/
diff --git a/Tests/CSAPIMapperTests.m b/Tests/CSAPIMapperTests.m
index 3b7c948..b9be05a 100644
--- a/Tests/CSAPIMapperTests.m
+++ b/Tests/CSAPIMapperTests.m
@@ -52,6 +52,8 @@ @interface TestTestObject : NSObject
@property (nonatomic, readwrite) BOOL falseBool;
@property (nonatomic, strong) NSString *subSubValue;
@property (nonatomic, strong) NSArray *subArrayValue;
+@property (nonatomic, strong) NSArray *subDictionaryValue;
+@property (nonatomic, strong) NSArray *subArrayLegacyValue;
@end
@@ -211,16 +213,36 @@ - (void)testCompoundSubtype
}
-- (void)testArraySubtype
+- (void)testCollectionAsDictionarySubtype
+{
+ TestTestObject *o = [[TestTestObject alloc] init];
+
+ [o mapAttributesWithDictionary:@{ @"test_subdictionary" : @{@"Object1" : @{@"test_trivial" : @"Test1"}, @"Object2" : @{@"test_trivial" : @"Test2"}, @"Object3" : @{@"test_trivial" : @"Test3"}}}];
+
+ STAssertEqualObjects([[o.subDictionaryValue objectAtIndex:0] testTrivial], @"Test1", @"1");
+ STAssertEqualObjects([[o.subDictionaryValue objectAtIndex:1] testTrivial], @"Test2", @"2");
+ STAssertEqualObjects([[o.subDictionaryValue objectAtIndex:2] testTrivial], @"Test3", @"3");
+}
+
+
+- (void)testCollectionAsArraySubtype
{
TestTestObject *o = [[TestTestObject alloc] init];
[o mapAttributesWithDictionary:@{ @"test_subarray" : @[ @{@"test_trivial" : @"Test1"}, @{@"test_trivial" : @"Test2"}, @{@"test_trivial" : @"Test3"}] }];
+ STAssertEqualObjects([[o.subArrayValue objectAtIndex:0] testTrivial], @"Test1", @"1");
+ STAssertEqualObjects([[o.subArrayValue objectAtIndex:1] testTrivial], @"Test2", @"2");
+ STAssertEqualObjects([[o.subArrayValue objectAtIndex:2] testTrivial], @"Test3", @"3");
+}
+
+- (void)testCollectionAsLegacyArraySubtype
+{
+ TestTestObject *o = [[TestTestObject alloc] init];
+ [o mapAttributesWithDictionary:@{ @"test_subarray" : @[ @{@"test_trivial" : @"Test1"}, @{@"test_trivial" : @"Test2"}, @{@"test_trivial" : @"Test3"}] }];
STAssertEqualObjects([[o.subArrayValue objectAtIndex:0] testTrivial], @"Test1", nil);
STAssertEqualObjects([[o.subArrayValue objectAtIndex:1] testTrivial], @"Test2", nil);
STAssertEqualObjects([[o.subArrayValue objectAtIndex:2] testTrivial], @"Test3", nil);
}
-
- (void)testJsonMapping
{
TestJsonMappedObject *o = [TestJsonMappedObject new];
diff --git a/Tests/TestTestObject.plist b/Tests/TestTestObject.plist
index d19de79..9523b2e 100644
--- a/Tests/TestTestObject.plist
+++ b/Tests/TestTestObject.plist
@@ -92,6 +92,24 @@
subArrayValue
+
+ type
+ NSArray
+ key
+ test_subarray
+ collection_subtype
+ TestTestSubtype
+
+ subDictionaryValue
+
+ type
+ NSDictionary
+ key
+ test_subdictionary
+ collection_subtype
+ TestTestSubtype
+
+ subArrayLegacyValue
type
NSArray