skip to Main Content

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?

2

Answers


  1. 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
    }
    
    Login or Signup to reply.
  2. So, if I understood correctly, you have already a struct/class named Item, so here are a few alternatives from your initial code:

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

    The struct name doesn’t have to be Item, you can just rename it:

    struct Order: Codable {
        let items: [Product]
    }
    
    struct Product: Codable {
        let id: Int
    }
    

    You can nest the Item:

    struct Order: Codable {
        let items: [Order.Item] //or [Item]
    
        struct Item: Codable {
            let id: Int
        }
    }
    

    So it’s still "Item", but it’s Order.Item. Inside the Order, it should try to use Order.Item by default when writing Item.
    If you need to differentiate them later, it’s Order.Item and App.Item where App is your AppName, or Framework.Item if Item is inside another framework.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search