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

Posted

技术标签:

【中文标题】如何使用 AlamoFireObjectMapper 动态映射 JSON 中的值,该值取决于同一 JSON 中的另一个值?【英文标题】:How can I dinamically map a value in a JSON that depends upon another value in the same JSON with AlamoFireObjectMapper? 【发布时间】:2017-03-16 13:38:03 【问题描述】:

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

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

[
    
        "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 等),我通常可以使用协议或超类进行管理。

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

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

【问题讨论】:

【参考方案1】:

正如您提到的,属性对象似乎没有任何重叠,因此除非您不共享整个代码,否则将它们全部作为子类或符合协议没有多大意义。

在摘要中,您可以进行自定义转换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&lt;Animal&gt;.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

【讨论】:

所以,我基本上应该为每个类定义一个转换,对吧?如果我需要整个类是多态的而不仅仅是属性 var,你知道如何应用它吗?

以上是关于如何使用 AlamoFireObjectMapper 动态映射 JSON 中的值,该值取决于同一 JSON 中的另一个值?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

如何使用laravel保存所有行数据每个行名或相等

如何使用 Math.Net 连接矩阵。如何使用 Math.Net 调用特定的行或列?

WSARecv 如何使用 lpOverlapped?如何手动发出事件信号?