I setup an example that better match your situation in order to give you an overview on how to parse
and access your JSON
information dynamically with a Dictionary
data type:
import Foundation
let jsonData = """
{
"images": {
"750": {
"src": "https:\\/\\/some_website.co.uk/cms/product_image/some_image.jpg",
"url": "https:\\/\\/some_website.co.uk/cms/product_image/some_image.jpg",
"width": 750
}
}
}
"""
let json = jsonData.data(using: .utf8)!
public struct Results: Codable {
public var images: [String:Image] = [:]
enum CodingKeys: String, CodingKey {
case images = "images"
}
}
public struct Image: Codable {
public var src: String = ""
public var url: String = ""
public var width: Int = 0
enum CodingKeys: String, CodingKey {
case src = "src"
case url = "url"
case width = "width"
}
}
if let results = try? JSONDecoder().decode(Results.self, from: json) {
let imagesDict = results.images
for (key, value) in imagesDict {
print("Key: \(key)")
print("Value: \(value)")
}
}
If you try this snippet it will give you this output printed:
Key: 750
Value: Image(src: "https://some_website.co.uk/cms/product_image/some_image.jpg", url: "https://some_website.co.uk/cms/product_image/some_image.jpg", width: 750)
You can try out the snippet above online, if you copy paste it here and run it: http://online.swiftplayground.run/
### UPDATE (in response to comment)
In response to your comment, I found it easier to setup another example to show you how you can achieve that with your exact code sample that you shared in the comment itself.
I left everything as class and just added images
in order to leave you an overview on how to achieve that.
In the end, I'd suggest to rename Products
and Attributes
into Product
and Attribute
. Also if there is no strong reason on why you choosed the model
to be class
, just change them to struct
and as well if there is no strong reasons to keep most of the attributes of each model optional
give them a default value as I did in the example above if you are always expecting some values/attributes to be there.
You can try and run this snippet as well in http://online.swiftplayground.run to try it out:
import Foundation
let jsonData = """
{
"data": [
{
"title": "titlex",
"description": "descx",
"list_price": "123,456",
"attributes": [
{
"title": "titlex",
"unit": "unitx",
"value": "valuex"
}
],
"images": {
"750": {
"src": "https:\\/\\/some_website.co.uk/cms/product_image/some_image.jpg",
"url": "https:\\/\\/some_website.co.uk/cms/product_image/some_image.jpg",
"width": 750
}
}
}
]
}
"""
let json = jsonData.data(using: .utf8)!
class AllProducts: Codable {
let data: [Products]
init(data: [Products]) {
self.data = data
}
}
class Products: Codable {
let title: String?
let description: String?
let list_price: String?
let attributes: [Attributes]?
let images: [String:Image]?
init(title: String, description: String, list_price: String, attributes: [Attributes], images: [String:Image]) {
self.title = title
self.description = description
self.list_price = list_price
self.attributes = attributes
self.images = images
}
}
class Attributes: Codable {
let title: String?
let unit: String?
let value: String?
init(title: String, unit: String, value: String) {
self.title = title
self.unit = unit
self.value = value
}
}
class Image: Codable {
let src: String?
let url: String?
let width: Int?
init(src: String, url: String, width: Int) {
self.src = src
self.url = url
self.width = width
}
}
// parsing/decoding
if let results = try? JSONDecoder().decode(AllProducts.self, from: json) {
if let imagesDict = results.data[0].images {
// there is an "images" for product at position 0 (the only one in my json example)
for (key, value) in imagesDict {
print("Key: \(key)")
print("Value src: \(value.src)")
print("Value url: \(value.url)")
print("Value width: \(value.width)")
}
}
}
Output
Key: 750
Value src: Optional("https://some_website.co.uk/cms/product_image/some_image.jpg")
Value url: Optional("https://some_website.co.uk/cms/product_image/some_image.jpg")
Value width: Optional(750)