当嵌套对象是以字符串表示的动态数字时,从JSON访问该对象

当嵌套对象是以字符串表示的动态数字时,从JSON访问该对象,json,swift,xcode,api,jsondecoder,Json,Swift,Xcode,Api,Jsondecoder,我正在使用XCode(10.2.1)和Swift(5.0)从API访问数据,遇到了一个似乎找不到答案的问题。我能够从API的所有其他部分获取数据,除了一个被命名为数字字符串“750”的部分,我不知道当我不能使用jsonDecoder可以读取的变量时如何获取数据 这是一个我知道行不通的例子,但让你知道我在尝试做什么 class Images: Codable { let "750": String init("750": String){ self."750" =

我正在使用XCode(10.2.1)和Swift(5.0)从API访问数据,遇到了一个似乎找不到答案的问题。我能够从API的所有其他部分获取数据,除了一个被命名为数字字符串“750”的部分,我不知道当我不能使用jsonDecoder可以读取的变量时如何获取数据

这是一个我知道行不通的例子,但让你知道我在尝试做什么

class Images: Codable {
    let "750": String

    init("750": String){
        self."750" = "750"
    }
}

下面是我试图从中获取图像的API的一个片段:

  "id": "069f7f26",
      "sku": "AP",
      "title": "Pizza",
      "description": "A really great pizza",
      "list_price": "9.95",
      "is_vatable": true,
      "is_for_sale": false,
      "age_restricted": false,
      "box_limit": 2,
      "always_on_menu": false,
      "volume": null,
      "zone": null,
      "created_at": "2017-03-06T10:52:43+00:00",
      "attributes": [
        {
          "id": "670f0e7c",
          "title": "Allergen",
          "unit": null,
          "value": "Products manufactured in a nut environment"
        },
        {
          "id": "c29e7",
          "title": "Weight",
          "unit": "g",
          "value": "300"
        }
      ],
      "tags": [

      ],
      "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
        }
      }
    },

我设置了一个更好地匹配您的情况的示例,以便让您概括了解如何使用
字典
数据类型动态地
解析
和访问
JSON
信息:

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)")
    }
}
如果您尝试此代码段,它将为您提供以下输出:

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)
您可以在线试用上面的代码段,如果您将其复制粘贴到此处并运行它:

###更新(回应评论)

作为对您的评论的回应,我发现设置另一个示例来向您展示如何使用您在评论中共享的确切代码示例来实现这一点更容易

我把所有的东西都放在课堂上,只是添加了
图像
,以便让您了解如何实现这一点

最后,我建议将
产品
属性
重命名为
产品
属性
。此外,如果没有充分的理由说明您为什么选择
型号
作为
类别
,只要将它们更改为
struct
,如果没有充分的理由保留每个模型的大多数属性
可选
,那么,如果您总是希望某些值/属性出现,请像我在上面的示例中所做的那样,给它们一个默认值

您也可以在中尝试运行此代码段以进行尝试:

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)")
        }
    }
}
输出

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)

Denis提供的以下解决方案应有效谢谢@Denis_lor。这看起来很棒,但我很难将其转换到当前的代码库中。我想我真正的问题是,我正试图对400多个项目进行排序,并将其放入表视图中。这是我目前拥有的。