Skip to content

Commit

Permalink
Merge pull request #207 from Hearst-DD/array-of-arrays
Browse files Browse the repository at this point in the history
- added ability to parse Arrays of Arrays of Mappable objects
  • Loading branch information
tristanhimmelman committed Sep 15, 2015
2 parents f2c1e8c + f2c2f91 commit 5275131
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 4 deletions.
21 changes: 18 additions & 3 deletions ObjectMapper/Core/FromJSON.swift
Expand Up @@ -48,9 +48,7 @@ internal final class FromJSON {

/// mappable object array
class func objectArray<N: Mappable>(inout field: Array<N>, object: AnyObject?) {
let parsedObjects = Mapper<N>().mapArray(object)

if let objects = parsedObjects {
if let objects = Mapper<N>().mapArray(object) {
field = objects
}
}
Expand All @@ -65,6 +63,23 @@ internal final class FromJSON {
field = Mapper().mapArray(object)
}

/// mappable object array
class func twoDimensionalObjectArray<N: Mappable>(inout field: Array<Array<N>>, object: AnyObject?) {
if let objects = Mapper<N>().mapArrayOfArrays(object) {
field = objects
}
}

/// optional mappable 2 dimentional object array
class func optionalTwoDimensionalObjectArray<N: Mappable>(inout field: Array<Array<N>>?, object: AnyObject?) {
field = Mapper().mapArrayOfArrays(object)
}

/// Implicitly unwrapped optional 2 dimentional mappable object array
class func optionalTwoDimensionalObjectArray<N: Mappable>(inout field: Array<Array<N>>!, object: AnyObject?) {
field = Mapper().mapArrayOfArrays(object)
}

/// Dctionary containing Mappable objects
class func objectDictionary<N: Mappable>(inout field: Dictionary<String, N>, object: AnyObject?) {
let parsedObjects = Mapper<N>().mapDictionary(object)
Expand Down
14 changes: 14 additions & 0 deletions ObjectMapper/Core/Mapper.swift
Expand Up @@ -213,6 +213,20 @@ public final class Mapper<N: Mappable> {
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]] {
Expand Down
29 changes: 29 additions & 0 deletions ObjectMapper/Core/Operators.swift
Expand Up @@ -347,6 +347,35 @@ public func <- <T: Mappable>(inout left: Array<T>!, right: Map) {
}
}

// MARK:- Array of Array of Mappable objects - Array<Array<T: Mappable>>

/// Array of Array Mappable objects
public func <- <T: Mappable>(inout left: Array<Array<T>>, 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 <- <T: Mappable>(inout left:Array<Array<T>>?, 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 <- <T: Mappable>(inout left: Array<Array<T>>!, 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<T: Mappable where T: Hashable>

/// Array of Mappable objects
Expand Down
15 changes: 15 additions & 0 deletions ObjectMapper/Core/ToJSON.swift
Expand Up @@ -121,6 +121,21 @@ internal final class ToJSON {
}
}

class func twoDimensionalObjectArray<N: Mappable>(field: Array<Array<N>>, 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<N: Mappable>(field: Array<Array<N>>?, map: Map) {
if let field = field {
twoDimensionalObjectArray(field, map: map)
}
}

class func objectSet<N: Mappable where N: Hashable>(field: Set<N>, map: Map) {
let JSONObjects = Mapper().toJSONSet(field)

Expand Down
42 changes: 41 additions & 1 deletion ObjectMapperTests/ObjectMapperTests.swift
Expand Up @@ -400,7 +400,7 @@ class ObjectMapperTests: XCTestCase {

func testImmutableMappable() {
let mapper = Mapper<Immutable>()
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())
Expand All @@ -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<ArrayTest>().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<ArrayTest>().toJSON(arrayTest!)
expect(backToJSON).notTo(beNil())

let arrayTest2 = Mapper<ArrayTest>().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<T: Mappable>: Mappable {
Expand Down Expand Up @@ -682,6 +711,17 @@ class ExampleEnumDictionary: Mappable {
}
}

class ArrayTest: Mappable {

var twoDimensionalArray: Array<Array<Base>>?

required init?(_ map: Map){}

func mapping(map: Map) {
twoDimensionalArray <- map["twoDimensionalArray"]
}
}

struct Immutable: Equatable {
let prop1: String
let prop2: Int
Expand Down

0 comments on commit 5275131

Please sign in to comment.