ios - 我如何使用 AlamoFireObjectMapper 动态映射 JSON 中的值,该值取决于同一 JSON 中的另一个值?

标签 ios json swift alamofire objectmapper

TL;DR 我想根据数组中存在的字段 type 的值,对存在于数组的每个元素中的字段 attributes(一个对象)进行建模相同的元素。

想象一下以下场景:我有一个端点可以提供有关动物的信息。有不同的动物,每一种都有不同的属性(我们可以假设一个父类(super class),但将所有属性放在一起是没有意义的)

[
    {
        "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 等),我可以使用协议(protocol)或父类(super class)进行一般管理。

问题是我不知道如何告诉映射器根据属性“type”的值,当从 JSON 生成对象“attributes”时,我不知道'希望它是父类(super class),而是特定的具体类。

那么,我如何告诉映射器if type == "DOG" 属性对象必须是 DogAttributes 的实例?

最佳答案

正如您提到的,属性对象似乎没有任何重叠,因此将它们全部设为子类或遵守协议(protocol)没有多大意义,除非您不共享全部代码。

在摘要中,您可以进行自定义转换 https://github.com/Hearst-DD/ObjectMapper#custom-transforms .在自定义转换中,您描述了如何从 JSON 转换为对象并返回。

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 { }

编辑

如果你想以不同的方式解析每个对象,那么而不是调用 Mapper<Animal>.mapArray(JSONString:string) ,您需要遍历 json 数组并传递不同的映射类。

如果你有

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
}

关于ios - 我如何使用 AlamoFireObjectMapper 动态映射 JSON 中的值,该值取决于同一 JSON 中的另一个值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42835699/

相关文章:

ios - 动画后更改 ViewController

ios - Swift:状态栏颜色与导航栏颜色不同

java - fastxml jackson 2.0+ 和 MixIn

ios - Base64 或 UIImage。

ios - SecKeyRawVerify 和 OSError -9809

ios - 调用 ExtensionDelegate 为 Complication 创建/刷新数据

JavaScript访问本地json

c# - 元组的 Json 反序列化问题?

ios - 我如何测试 View Controller 是否已呈现?

ios - UITextfield 有奇怪的效果