Object Mapper — разбор массива [AnyObject]

У меня есть ответ JSON многотипных объектов из API.

Он имеет свойство type внутри. Теперь я пытаюсь применить какое-то автоматическое сопоставление на основе свойства type, но я никак не могу заставить его работать.

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
}

ошибка, которую я получаю, заключается в том, что Type is not a type


person yershuachu    schedule 17.08.2016    source источник
comment
Извините, но у вас есть эти модели внутри проекта? вы не можете сопоставить тип, если он еще не существует. Путь слишком долог, если вы хотите сопоставить любой новый тип, описанный в вашем Json.   -  person Patonz    schedule 17.08.2016
comment
@Patonz - да. Это существующие отображаемые объекты :)   -  person yershuachu    schedule 17.08.2016


Ответы (1)


То, что вы пытаетесь сделать, на самом деле невозможно, потому что связанные с шаблоном типы не являются временем выполнения. Компилятор должен знать тип во время компиляции.

Мы можем сделать это немного по-другому, используя перечисления:

enum ModelClassMap: String {
    case FirstType = "first_type"

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

И в вашем цикле for вы можете попробовать преобразовать строку в перечисление:

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
}
person Dmytro Kabyshev    schedule 17.08.2016
comment
Это то, что я предположил. Спасибо за ответ. Тогда я придерживаюсь любой карты простого переключения. - person yershuachu; 17.08.2016