简体   繁体   中英

How can a JSON array listing different objects be decoded into multiple structs using Swift's JSONDecoder?

Using this JSON object as an example:

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

Note the animal and plant types have some different properties and some shared properties.

How would JSONDecoder be used in Swift to convert these into the following structs:

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

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

You can change your structs a bit, like this

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

Try to make consistent array structure

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


  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM