0

A similar question was asked here: Codable Handle dynamic key at root

However, the answer in the above question doesn't have much explanation so I don't understand it.

So my question:

I have an API that output this JSON response:

 {
        "category1": {
            "products": [{
                "title": "Love",
                "id": "120",
                "url": "https:",
                "details": "",
                "duration": "22.27",
                "category": "category1",
                "sub_category": "sub cat name",
                "date_added": "2018-11-12"

            }, {
                "title": "Love",
                "id": "120",
                "url": "https:",
                "details": "",
                "duration": "22.27",
                "category": "category1",
                "sub_category": "sub cat name",
                "date_added": "2018-11-12"

            }]
        },

        "category2": {
            "products": [{
                "title": "Love",
                "id": "120",
                "url": "https:",
                "details": "",
                "duration": "22.27",
                "category": "category2",
                "sub_category": "sub cat name",
                "date_added": "2018-11-12"

            }, {
                "title": "Love",
                "id": "120",
                "url": "https:",
                "details": "",
                "duration": "22.27",
                "category": "category2",
                "sub_category": "sub cat name",
                "date_added": "2018-11-12"

            }]
        }
    }

The category1, category2 etc are dynamic categories.

So I can't really create a struct like this:

// MARK: - Welcome
struct Welcome: Codable {
    let category1, category2: Category
}

// MARK: - Category
struct Category: Codable {
    let products: [Product]
}

Reason being that the category names are dynamic and they are at the Root.

is there a way to do this?

drago
  • 1,148
  • 2
  • 16
  • 35

2 Answers2

1

You only need

struct Category: Codable {
   let products: [Product]
}

with

let res = try JSONDecoder().decode([String:Category].self, from: data) 
print(res["category1"]?.products)
let names = Array(res.keys)
print(names)
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
  • the categories are dynamic! so the category1, category2 etc are all dynamic names and they could change. – drago Jun 21 '21 at 14:03
  • 1
    this will work for dynamic names , optional `?` here `res["category1"]?` will return `nil` if key named `category1` doesn't exist – Shehata Gamal Jun 21 '21 at 14:04
  • what if I don't know the name of any of the categories?! – drago Jun 21 '21 at 14:24
  • 1
    i said this is the answer for dynamic category names , have you tried it ??? – Shehata Gamal Jun 21 '21 at 14:25
  • Yes, I have and it sort of works but as I said, I won't know the name of every category! So I can't do `res["category1"]?.products` or `res["category2"]?.products` because I don't know what category names the API will return! – drago Jun 21 '21 at 14:28
0

Simply just use as dictionary, like:

struct Welcome: Codable {
   let category:[String:[Category]] 
}
struct Category: Codable {
    let products: [Product]
}
Dris
  • 881
  • 8
  • 19