如何使用Swift的JSONDecoder将列出不同对象的JSON数组解码为多个结构?

时间:2018-03-15 11:26:25

标签: json swift swift4 codable decodable

以此JSON对象为例:

{
  data: [
    {
      type: "animal"
      name: "dog"
      consumes: "dog food"
    },
    {
      type: "plant"
      name: "cactus"
      environment: "desert"
    }
  ]
}

请注意,animalplant类型具有一些不同的属性和一些共享属性。

如何在Swift中使用JSONDecoder将这些转换为以下结构:

struct Animal: Decodable {
  let name: String
  let consumes: String
}

struct Plant: Decodable {
  let name: String
  let environment: String
}

2 个答案:

答案 0 :(得分:1)

您可以稍微改变一下结构,比如

enum ItemType {
    case animal(consumes: String)
    case plant(environment: String)
    case unknown
}

struct Item: Decodable {
    let name: String
    let type: ItemType

    enum CodingKeys: CodingKey {
        case name
        case type
        case consumes
        case environment
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)

        self.name = try values.decode(String.self, forKey: .name)
        let type = try values.decode(String.self, forKey: .type)
        switch type {
        case "animal":
            let food = try values.decode(String.self, forKey: .consumes)
            self.type = .animal(consumes: food)
        case "plant":
            let environment = try values.decode(String.self, forKey: .environment)
            self.type = .plant(environment: environment)
        default:
            self.type = .unknown
        }
    }
}

答案 1 :(得分:0)

尝试制作一致的数组结构

{
  data: {
animals:[
     {
         type: "animal"
         name: "Cat"
         consumes: "cat food"
    },
    {
         type: "animal"
         name: "dog"
         consumes: "dog food"
    }
],
plants:[
   {
         type: "plant"
         name: "cactus"
         environment: "desert"
    },
   {
         type: "plant"
         name: "Plam"
         environment: "hill"
    }
]


  }
}