From f2c2f916a25d237c843f214623eb3c53116d8962 Mon Sep 17 00:00:00 2001 From: Tristan Himmelman Date: Tue, 15 Sep 2015 15:32:33 -0400 Subject: [PATCH] - added ability to parse Arrays of Arrays of Mappable objects --- ObjectMapper/Core/FromJSON.swift | 21 ++++++++++-- ObjectMapper/Core/Mapper.swift | 14 ++++++++ ObjectMapper/Core/Operators.swift | 29 ++++++++++++++++ ObjectMapper/Core/ToJSON.swift | 15 ++++++++ ObjectMapperTests/ObjectMapperTests.swift | 42 ++++++++++++++++++++++- 5 files changed, 117 insertions(+), 4 deletions(-) diff --git a/ObjectMapper/Core/FromJSON.swift b/ObjectMapper/Core/FromJSON.swift index 92020422..c2181e9f 100755 --- a/ObjectMapper/Core/FromJSON.swift +++ b/ObjectMapper/Core/FromJSON.swift @@ -48,9 +48,7 @@ internal final class FromJSON { /// mappable object array class func objectArray(inout field: Array, object: AnyObject?) { - let parsedObjects = Mapper().mapArray(object) - - if let objects = parsedObjects { + if let objects = Mapper().mapArray(object) { field = objects } } @@ -65,6 +63,23 @@ internal final class FromJSON { field = Mapper().mapArray(object) } + /// mappable object array + class func twoDimensionalObjectArray(inout field: Array>, object: AnyObject?) { + if let objects = Mapper().mapArrayOfArrays(object) { + field = objects + } + } + + /// optional mappable 2 dimentional object array + class func optionalTwoDimensionalObjectArray(inout field: Array>?, object: AnyObject?) { + field = Mapper().mapArrayOfArrays(object) + } + + /// Implicitly unwrapped optional 2 dimentional mappable object array + class func optionalTwoDimensionalObjectArray(inout field: Array>!, object: AnyObject?) { + field = Mapper().mapArrayOfArrays(object) + } + /// Dctionary containing Mappable objects class func objectDictionary(inout field: Dictionary, object: AnyObject?) { let parsedObjects = Mapper().mapDictionary(object) diff --git a/ObjectMapper/Core/Mapper.swift b/ObjectMapper/Core/Mapper.swift index 5e70095f..50cdbcf6 100755 --- a/ObjectMapper/Core/Mapper.swift +++ b/ObjectMapper/Core/Mapper.swift @@ -213,6 +213,20 @@ public final class Mapper { return JSONArray.flatMap(map) } + /// Maps an 2 dimentional array of JSON dictionaries to a 2 dimentional array of Mappable objects + public func mapArrayOfArrays(JSON: AnyObject?) -> [[N]]? { + if let JSONArray = JSON as? [[[String : AnyObject]]] { + var objectArray = [[N]]() + + for innerJSONArray in JSONArray { + objectArray.append(mapArray(innerJSONArray)) + } + return objectArray + } + + return nil + } + /// Maps a JSON object to a dictionary of Mappable objects if it is a JSON dictionary of dictionaries, or returns nil. public func mapDictionary(JSON: AnyObject?) -> [String : N]? { if let JSONDictionary = JSON as? [String : [String : AnyObject]] { diff --git a/ObjectMapper/Core/Operators.swift b/ObjectMapper/Core/Operators.swift index a7b56472..5eba6385 100755 --- a/ObjectMapper/Core/Operators.swift +++ b/ObjectMapper/Core/Operators.swift @@ -347,6 +347,35 @@ public func <- (inout left: Array!, right: Map) { } } +// MARK:- Array of Array of Mappable objects - Array> + +/// Array of Array Mappable objects +public func <- (inout left: Array>, right: Map) { + if right.mappingType == MappingType.FromJSON { + FromJSON.twoDimensionalObjectArray(&left, object: right.currentValue) + } else { + ToJSON.twoDimensionalObjectArray(left, map: right) + } +} + +/// Optional array of Mappable objects +public func <- (inout left:Array>?, right: Map) { + if right.mappingType == MappingType.FromJSON { + FromJSON.optionalTwoDimensionalObjectArray(&left, object: right.currentValue) + } else { + ToJSON.optionalTwoDimensionalObjectArray(left, map: right) + } +} + +/// Implicitly unwrapped Optional array of Mappable objects +public func <- (inout left: Array>!, right: Map) { + if right.mappingType == MappingType.FromJSON { + FromJSON.optionalTwoDimensionalObjectArray(&left, object: right.currentValue) + } else { + ToJSON.optionalTwoDimensionalObjectArray(left, map: right) + } +} + // MARK:- Set of Mappable objects - Set /// Array of Mappable objects diff --git a/ObjectMapper/Core/ToJSON.swift b/ObjectMapper/Core/ToJSON.swift index d6507f50..ac5ccf1a 100644 --- a/ObjectMapper/Core/ToJSON.swift +++ b/ObjectMapper/Core/ToJSON.swift @@ -121,6 +121,21 @@ internal final class ToJSON { } } + class func twoDimensionalObjectArray(field: Array>, map: Map) { + var array = [[[String : AnyObject]]]() + for innerArray in field { + let JSONObjects = Mapper().toJSONArray(innerArray) + array.append(JSONObjects) + } + setValue(array, map: map) + } + + class func optionalTwoDimensionalObjectArray(field: Array>?, map: Map) { + if let field = field { + twoDimensionalObjectArray(field, map: map) + } + } + class func objectSet(field: Set, map: Map) { let JSONObjects = Mapper().toJSONSet(field) diff --git a/ObjectMapperTests/ObjectMapperTests.swift b/ObjectMapperTests/ObjectMapperTests.swift index a17b869a..85d1d2a9 100644 --- a/ObjectMapperTests/ObjectMapperTests.swift +++ b/ObjectMapperTests/ObjectMapperTests.swift @@ -400,7 +400,7 @@ class ObjectMapperTests: XCTestCase { func testImmutableMappable() { let mapper = Mapper() - let JSON = [ "prop1": "Immutable!", "prop2": 255, "prop3": true ] + let JSON = ["prop1": "Immutable!", "prop2": 255, "prop3": true ] let immutable: Immutable! = mapper.map(JSON) expect(immutable).notTo(beNil()) @@ -416,6 +416,35 @@ class ObjectMapperTests: XCTestCase { let JSONFromObject = mapper.toJSON(immutable) expect(mapper.map(JSONFromObject)).to(equal(immutable)) } + + func testArrayOfArrayOfMappable() { + let base1 = "1" + let base2 = "2" + let base3 = "3" + let base4 = "4" + + let array1 = [["base": base1], ["base": base2], ["base": base3]] + let array2 = [["base": base4]] + let JSON = ["twoDimensionalArray":[array1, array2]] + + let arrayTest = Mapper().map(JSON) + expect(arrayTest).notTo(beNil()) + expect(arrayTest?.twoDimensionalArray?[0][0].base).to(equal(base1)) + expect(arrayTest?.twoDimensionalArray?[0][1].base).to(equal(base2)) + expect(arrayTest?.twoDimensionalArray?[0][2].base).to(equal(base3)) + expect(arrayTest?.twoDimensionalArray?[1][0].base).to(equal(base4)) + + expect(arrayTest?.twoDimensionalArray?[0].count).to(equal(array1.count)) + expect(arrayTest?.twoDimensionalArray?[1].count).to(equal(array2.count)) + + let backToJSON = Mapper().toJSON(arrayTest!) + expect(backToJSON).notTo(beNil()) + + let arrayTest2 = Mapper().map(backToJSON) + expect(arrayTest2).notTo(beNil()) + expect(arrayTest2?.twoDimensionalArray?[0][0].base).to(equal(arrayTest?.twoDimensionalArray?[0][0].base)) + expect(arrayTest2?.twoDimensionalArray?[0][1].base).to(equal(arrayTest?.twoDimensionalArray?[0][1].base)) + } } class Response: Mappable { @@ -682,6 +711,17 @@ class ExampleEnumDictionary: Mappable { } } +class ArrayTest: Mappable { + + var twoDimensionalArray: Array>? + + required init?(_ map: Map){} + + func mapping(map: Map) { + twoDimensionalArray <- map["twoDimensionalArray"] + } +} + struct Immutable: Equatable { let prop1: String let prop2: Int