Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use multiple CodingKeys for a single property

Tags:

swift

Is it possible to use multiple CodingKeys for a single property?

struct Foo: Decodable {

    enum CodingKeys: String, CodingKey {
        case contentIDs = "contentIds" || "Ids" || "IDs" // something like this?
    }

    let contentIDs: [UUID]
}
like image 560
Jonas Avatar asked Oct 04 '19 12:10

Jonas


2 Answers

You can do that by using multiple CodingKey enums and custom initializer. Let me show it by an example

enum CodingKeys: String, CodingKey {
    case name = "prettyName"
}

enum AnotherCodingKeys: String, CodingKey {
    case name
}

init(from decoder: Decoder) throws {
    let condition = true // or false
    if condition {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        name = try values.decode(String.self, forKey: .name)
    } else {
        let values = try decoder.container(keyedBy: AnotherCodingKeys.self)
        name = try values.decode(String.self, forKey: .name)
    }
}
like image 113
Gurkan Soykan Avatar answered Sep 18 '22 14:09

Gurkan Soykan


Implement the init(from:) initialiser and add custom parsing as per your requirement, i.e.

struct Foo: Decodable {
    let contentIDs: [String]

    enum CodingKeys: String, CodingKey, CaseIterable {
        case contentIds, Ids, IDs
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        if let key = container.allKeys.filter({ CodingKeys.allCases.contains($0) }).first, let ids = try container.decodeIfPresent([String].self, forKey: key) {
            self.contentIDs = ids
        } else {
            self.contentIDs = []
        }
    }
}
like image 28
PGDev Avatar answered Sep 18 '22 14:09

PGDev