'Decode heterogeneous array JSON using Swift decodable

This is the JSON I am trying to decode. The value of objectType decides what object to create.

{
  "options": [
    {
      "objectType": "OptionTypeA",
      "label": "optionALabel1",
      "value": "optionAValue1"
    },
    {
      "objectType": "OptionTypeB",
      "label": "optionBLabel",
      "value": "optionBValue"
    },
    {
      "objectType": "OptionTypeA",
      "label": "optionALabel2",
      "value": "optionAValue2"
    }
  ]
}

Say I have the 2 Option Types defined like so

public protocol OptionType {
  var label: String { get }
  var value: String { get }
}

struct OptionTypeA: Decodable {
  let label: String
  let value: String
  
  // and some others...
}

struct OptionTypeB: Decodable {
  let label: String
  let value: String
  
  // and some others...
}

struct Option: Decodable {
  let options: [OptionType]
  
  enum CodingKeys: String, CodingKey {
    case options
    case label
    case value
    case objectType
  }
  
  init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)
    var optionsContainer = try values.nestedUnkeyedContainer(forKey: .options)
    var options = [OptionType]()
    
    while !optionsContainer.isAtEnd {
      let itemContainer = try optionsContainer.nestedContainer(keyedBy: CodingKeys.self)
      
      switch try itemContainer.decode(String.self, forKey: .objectType) {
      // What should I do here so that I do not have to manually decode `OptionTypeA` and `OptionTypeB`?
      case "OptionTypeA": options.append() 
      case "OptionTypeB": options.append()
      default: fatalError("Unknown type")
      }
    }
    
    self.options = options
  }
}

I know I can then manually decode each key in itemContainer and create the individual option type objects in the switch case. But I do not want to do that. How can I just decode these objects?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source