Home > Enterprise >  Swift Codable on self-typed JSON [duplicate]
Swift Codable on self-typed JSON [duplicate]

Time:10-08

I'm trying to (at least) decode JSON that looks something like this:

{
    "type": "row",
    "title": "Hello...",
    "subtitle": "...from JSON"
}

However, "type" defines which Codable Type this represents (e.g. "row" to Row). I've seen many examples where "type" is one value and the rest are nested in a "payload" value like this:

{
    "type": "row",
    "payload: 
    {
        "title": "Hello...",
        "subtitle": "...from JSON"
    }
}

But in my scenario, it's flattened. How can I write a custom decoder that can read the type and THEN (re?)decode with that knowledge?

CodePudding user response:

This is a very small variation of the answer I have posted here: https://stackoverflow.com/a/69330151/669586

enum Item: Decodable {
    case data1(Data1)
    case data2(Data2)

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

        // read type first
        let type = try container.decode(String.self, forKey: .type)

        // using type, continue decoding and save decoded data
        switch type {
        case "type1":
            let data = try Data1(from: decoder)
            self = .data1(data)
        case "type2":
            let data = try Data2(from: decoder)
            self = .data2(data)
        default:
            throw DecodingError.unknownType
        }
    }

    private enum CodingKeys: String, CodingKey {
        case type
    }

    private enum DecodingError: String, Error {
        case unknownType
    }
}

struct Data1: Decodable {
}

struct Data2: Decodable {
}
  • Related