TL; DR我想根据同一元素中存在的字段attributes
的值,对数组中每个元素内存在的字段type
(对象)进行建模。
想象一下以下场景:我有一个端点,可以提供有关动物的信息。有不同的动物,每个动物都有不同的属性(我们可能会假设一个超类,但是将一个具有所有属性的类放在一起是没有意义的)
[
{
"name": "Lassie",
"type": "DOG",
"attributes": {
"hairColor": "gold",
"jumpHeight": "2 mts"
}
},
{
"name": "Rex",
"type": "DINOSAUR",
"attributes": {
"isCarnivore": "true",
}
},
{
"name": "Nemo",
"type": "FISH",
"attributes": {
"avgSwimSpeed": "10 km/h",
"hasInjuredFin": "false"
}
}
]
我使用AlamofireObjectMapper将JSON映射到我的模型,但我想要建模的是属性的不同类(DogAttributes,FishAttributes等),我通常可以使用协议或超类来管理
问题在于,当对象"属性"是从JSON生成的,我不希望它成为超类,而是一个特定的具体类。
那么,我如何告诉映射器if type == "DOG"
属性对象必须是DogAttributes的实例?
答案 0 :(得分:2)
正如您所提到的,属性对象似乎没有任何重叠,因此将它们全部作为子类或符合协议没有多大意义,除非您不共享整个代码。
在摘要中,您可以执行自定义转换https://github.com/Hearst-DD/ObjectMapper#custom-transforms。在自定义转换中,您将描述如何从JSON转换为Object并返回。
class Animal: StaticMappable {
var name:String
var type:String
var attributes:Atttributes
public override func mapping(map: Map) {
super.mapping(map: map)
name <- map["name"]
type <- map["type"]
if type == "DOG" {
attributes <- (map["attributes"], DogTransfrom())
} else if type == "DINOSAUR" {
attributes <- (map["attributes"], DinoTransfrom())
}
}
}
protocol Attributes { }
struct DogAttributes: Attributes { }
struct DinosaurAttributes: Attributes { }
修改强>
如果你想以不同的方式解析每个对象,那么你需要循环遍历json数组并传递不同的映射类,而不是调用Mapper<Animal>.mapArray(JSONString:string)
。
如果你有
class Animal: StaticMappable {}
class Dog: Animal {}
class Dinosaur: Animal{}
和你的解析方法(伪代码)
func parseJSON(json:JSON) -> [Animal] {
var animals = [Animal]()
for animal in json['animals'] {
if animal['type'].lowercased() == 'dog' {
let dog = Mapper<Dog>().map(JSONObject: animal.dictionaryObject)
animals.append(dog)
} else if animal['type'].lowercased() == 'dinosaur' {
let dino = Mapper<Dinosaur>().map(JSONObject: animal.dictionaryObject)
animals.append(dino)
}
}
return animals
}