Search code examples
jsonswiftxcodejsondecodercoda

Is there a way to decode a JSON key to a differently named codable property in struct in swift


I have and API that I am making a network request to and the API returns some JSON data.

From what I've seen, the most common and generally accepted way to handle that JSON data and work with it, is to make a Codable struct and then decode the JSON data to the struct Like this Hacking with Swift example.

I'm running into an issue though and need some help. There is some persistence code that is included in the Xcode project (that Xcode is not letting me alter) that utilizes a struct named "Item". The API I'm using has a key in the JSON also named "Item". When I make my Codable struct I (predictably) get an error saying that there is an "Invalid redeclaration of 'Item'" since its declared in persistence code.

My question: Is there a way to make a Codable struct and still be able to use the JSON decoding to map the "Item" field from the JSON data to a differently named field in the Codable struct (i.e. something like Items, or Products).

So lets say this is the JSON Data:

{
    "items": [
                 { "id": 12345 },
                 { "id": 67890 },
                 { "id": 10111 },
                 { "id": 21314 }
    ]
}

And this is the struct:

struct Order: Codable {
    let items: [Item]
}

struct Item: Codable {
    let id: Int
}

is there a way to rename Item (in my struct) to something else and still have the item from the JSON decoded to the struct?


Solution

  • yes you can "...map the "Item" field from the JSON data to a differently named field in the Codable struct (i.e. something like Items, or Products)",

    using enum CodingKeys:... for example:

    struct Order: Codable {
        let products: [Product]
        
        enum CodingKeys: String, CodingKey {
            case products = "items"
        }
    }
    
    struct Product: Codable {
        let product: Int
        
        enum CodingKeys: String, CodingKey {
            case product = "id"
        }
    }
    
    // alternatively keeping the id
    struct Product: Codable, Identifiable {
        let id: Int
    }