yershuachu yershuachu - 3 months ago 13
JSON Question

Object Mapper - parsing array of [AnyObject]

I have response JSON of multitype objects from API.

It has

type
property inside. Now I'm trying to apply some kind of automated mapping basing on
type
property, but I can't make it work in any means.

private let modelClassMap = [
"first_type": First.self
]

func createModelWithDictionary(json: [String: AnyObject]) -> [AnyObject] {
var items: [AnyObject]
if let items = json["items"] as? [[String: AnyObject]] {
for item in items {
if let typeString = item["type"] as? String {
var Type = self.modelClassMap[typeString]
items.append(Mapper<Type>().map(item))
}
}
}
return items
}


error I am getting is that
Type is not a type

Answer

What you're trying to do is not really possible, because template's associated types are not runtime. Compiler needs to know a type at compile time.

We can do it a bit differently, using enums:

enum ModelClassMap: String {
    case FirstType = "first_type"

    func map(item: [String: AnyObject]) -> AnyObject? {
        switch self {
        case FirstType:
            return Mapper<First>().map(item)
        }
    }
}

And in your for-loop you can try convert string to enum:

func createModelWithDictionary(json: [String: AnyObject]) -> [AnyObject] {
    var mappedItems: [AnyObject] = []
    if let items = json["items"] as? [[String: AnyObject]] {
        items.forEach() {
            if let typeString = $0["type"] as? String,
                let mappedType = ModelClassMap(rawValue: typeString),
                let mappedObject = mappedType.map($0) {
                // mappedObject represents an instance of required object, represented by "type"
                mappedItems.append(mappedObject)
            }
        }
    }
    return mappedItems
}