thoughtbot/Argo

How to decode dynamic keys

iOSCoderJane opened this issue · 2 comments

public struct GenericCodingKey: CodingKey {
    public let stringValue: String

    public init?(stringValue: String) {
        self.stringValue = stringValue
        self.intValue = nil
    }

    public var intValue: Int?

    public init?(intValue: Int) {
        self.intValue = intValue
        self.stringValue = String(intValue)
    }

    public init(name: String) {
        self.init(stringValue: name)!
    }
}

public struct TestModel: Codable {
    public let id: String // in json this key maybe have diffrent string, just like that have tow key named "code" or "tagcode"

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: GenericCodingKey.self)
        if container.contains(GenericCodingKey(name: "code")) {
            self.id = try container.decode(String.self, forKey: GenericCodingKey(name: "code"))
        } else {
            self.id = try container.decode(String.self, forKey: GenericCodingKey(name: "tagcode"))
        }
    }
}

Sample JSON

{
  "code": "123"
}

{
  "tagcode": "123"
}

I want to konw how to resovle this problem. thank you~

Argo doesn't have anything to do with the Codable protocol(s) introduced in Swift 4. I suggest you use Stack Overflow. I also believe questions like this have been answered there before.

FWIW, in Argo you'd use Alternative for this:

let id: Decoded<String> = json <| "code" <|> json <| "tagcode"

But as @jshier pointed out, this won't work with Codable. I'm going to go ahead and close this.