SwiftUI JSON model with different ID name

I'm trying to read JSON from an api out of my control and the format of the JSON is such that the ID field is not called ID... it's swimmerID. How do I create a model that conforms to Identifiable, but with a different id name? I've been searching for an answer and I've come up with nothing. Any one have any suggestions?

Accepted Reply

There's an easy way and a complicated way.


The easy way is to define your own `id` property on the structure which returns the value of `swimmerID`:


// Contains the raw JSON stuff
struct Swimmer {
    var swimmerID: Int // or String, UUID, whatever's in your JSON
    // more model values from JSON
}

// Now conform to Identifiable
extension Swimmer: Identifiable {
    var id: Int { return swimmerID }
}


The more complex variant involves telling the JSONDecoder exactly what variables are available, and what they're called in both Swift and JSON, noting where there are differences. You can do this (for any decoder, actually) by defining a CodingKeys type inside your Codable type. A common pattern is to use an enum where each case is a String; you then specify the string value manually for any case where JSON uses a different value than the one you want in Swift. The enum case name should match the Swift variable, and the string name would match the JSON payload:


struct Swimmer: Codable, Identifiable {
    var id: Int
    var name: String
    // declare other properties here

    // now you define the coding keys
    enum CodingKeys: String {
        case id = "swimmerID"
        case name // = "name"
        // etc.
        // be sure to include ALL properties here: anything not
        // listed in this enum will NOT be decoded, and the
        // decoder will throw an error if it finds something to
        // decode which is not represented here.
    }
}


Personally, if the only problem is converting "swimmerID" into "id", and everything else is fine as it is, I'd go with the first option.

Replies

There's an easy way and a complicated way.


The easy way is to define your own `id` property on the structure which returns the value of `swimmerID`:


// Contains the raw JSON stuff
struct Swimmer {
    var swimmerID: Int // or String, UUID, whatever's in your JSON
    // more model values from JSON
}

// Now conform to Identifiable
extension Swimmer: Identifiable {
    var id: Int { return swimmerID }
}


The more complex variant involves telling the JSONDecoder exactly what variables are available, and what they're called in both Swift and JSON, noting where there are differences. You can do this (for any decoder, actually) by defining a CodingKeys type inside your Codable type. A common pattern is to use an enum where each case is a String; you then specify the string value manually for any case where JSON uses a different value than the one you want in Swift. The enum case name should match the Swift variable, and the string name would match the JSON payload:


struct Swimmer: Codable, Identifiable {
    var id: Int
    var name: String
    // declare other properties here

    // now you define the coding keys
    enum CodingKeys: String {
        case id = "swimmerID"
        case name // = "name"
        // etc.
        // be sure to include ALL properties here: anything not
        // listed in this enum will NOT be decoded, and the
        // decoder will throw an error if it finds something to
        // decode which is not represented here.
    }
}


Personally, if the only problem is converting "swimmerID" into "id", and everything else is fine as it is, I'd go with the first option.