I have a JSON object that looks something like this:
{
"name": "Acid Arrow",
"school": {
"name": "Evocation",
"url": "http://www.dnd5eapi.co/api/magic-schools/5"
}
}
that I would like to model in Swift as the following:
struct Spell: Decodeable {
let name: String
let school: MagicSchool
}
enum MagicSchool: String {
case abjuration = "Abjuration"
case abjuration = "Abjuration"
case conjuration = "Conjuration"
case divination = "Divination"
case enchantment = "Enchantment"
case evocation = "Evocation"
case illusion = "Illusion"
case necromancy = "Necromancy"
case transmutation = "Transmutation"
}
The only ways I can find to reduce the JSON school
dictionary down to a single enumeration value is to implement the entire Decodeable
by providing a custom init(from decoder: Decoder)
initializer that would look something like this:
extension Spell: Decodeable {
init(from decoder: Decoder) {
let values = try decoder.container(keyedBy: CodingKeys.self)
// manually map to the spell name
name = try values.decode(String.self, forKey: .name)
// manually decode **school** into a dictionary
let jsonSchool = try values.decode(Dictionary<String,String>.self, forKey: .school)
// extract the "name" property from the dict and assign it as `MagicSchool` enum
school = MagicSchool(rawValue: jsonSchool["name"])
}
}
But it doesn't like it because of a type conflict on the key type for Spell.school
Am I trying to do this the wrong way? Is there a simpler way to transform a complex type into a basic type or to specify a path in the mapping?