JSON decode for a strange json data

My JSON file like this:

{
"armor": {
  "param": [
    {
      "skill_list": [
         {
          "Skill": 56
        },
        {
          "Skill": 4
        },
        "None",
        "None",
        "None"
      ]
    },
    {
      "skill_list": [
        {
          "Skill": 103
        },
        "None",
        "None",
        "None",
        "None"
      ]
    }
    ]
}
}

I don't know how to define a struct to this JSON data, and I don't want to use SwiftyJSON package.

Is there a way to define a struct to decode this JSON data?

Just like

JSONDecoder().decode(MyStruct.self, from: data)

You may use either JSONSerialization:

let data = json.data(using: .utf8)!

func jsonTest1() {
    let x = try! JSONSerialization.jsonObject(with: data, options: [])
    print(x)
}

or a custom decoder:

struct Payload: Decodable {
    struct Armor: Decodable {
        struct Param: Decodable {
            struct Element: Decodable {
                var skill: Int?
            }
            var skill_list: [Element]
        }
        var param: [Param]
    }
    var armor: Armor
}

extension Payload.Armor.Param.Element {
    enum CodingKeys: String, CodingKey {
        case skill = "Skill"
    }
    init(from decoder: Decoder) throws {
        if let container = try? decoder.singleValueContainer(), let string = try? container.decode(String.self), string == "None" {
            self.init(skill: nil)
        } else {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            let skill = try container.decode(Int.self, forKey: .skill)
            self.init(skill: skill)
        }
    }
}

func jsonTest2() {
    let x = try! JSONDecoder().decode(Payload.self, from: data)
    print(x)
}

with JSONSerialization it is quicker to start with as no extra code is required upfront, but it is less clean and somewhat harder to use the resulting structure.

2 Likes

thank u! you are legend