Swift 解码器,正在尝试解码带有图层的文件

Swift Decoder, trying to decode file with layers

我如何使用 JSONDecoder().decode

解码此 json 文件
{
  "text": "pear",
  "parsed": [
    {
      "food": {
        "foodId": "food_bq6stkiaxkwhxia9q4v7wanjnew0",
        "label": "Pear",
        "nutrients": {
          "ENERC_KCAL": 57,
          "PROCNT": 0.36,
          "FAT": 0.14,
          "CHOCDF": 15.23,
          "FIBTG": 3.1
        },
        "category": "Generic foods",
        "categoryLabel": "food",
        "image": "https://www.edamam.com/food-img/65a/65aec51d264db28bbe27117c9fdaaca7.jpg"
      }
    }
  ],
  "hints": [
    {
      "food": {
        "foodId": "food_bq6stkiaxkwhxia9q4v7wanjnew0",
        "label": "Pear",
        "nutrients": {
          "ENERC_KCAL": 57,
          "PROCNT": 0.36,
          "FAT": 0.14,
          "CHOCDF": 15.23,
          "FIBTG": 3.1
        },
        "category": "Generic foods",
        "categoryLabel": "food",
        "image": "https://www.edamam.com/food-img/65a/65aec51d264db28bbe27117c9fdaaca7.jpg"
      },
      "measures": [
        {
          "uri": "http://www.edamam.com/ontologies/edamam.owl#Measure_unit",
          "label": "Whole",
          "qualified": [
            {
              "qualifiers": [
                {
                  "uri": "http://www.edamam.com/ontologies/edamam.owl#Qualifier_large",
                  "label": "large"
                }
              ]
            },
            {
              "qualifiers": [
                {
                  "uri": "http://www.edamam.com/ontologies/edamam.owl#Qualifier_small",
                  "label": "small"
                }
              ]
            },
            {
              "qualifiers": [
                {
                  "uri": "http://www.edamam.com/ontologies/edamam.owl#Qualifier_medium",
                  "label": "medium"
                }
              ]
            }
          ]
        },
        {
          "uri": "http://www.edamam.com/ontologies/edamam.owl#Measure_serving",
          "label": "Serving"
        },
        {
          "uri": "http://www.edamam.com/ontologies/edamam.owl#Measure_half",
          "label": "Half"
        },
        {
          "uri": "http://www.edamam.com/ontologies/edamam.owl#Measure_slice",
          "label": "Slice"
        },
        {
          "uri": "http://www.edamam.com/ontologies/edamam.owl#Measure_gram",
          "label": "Gram"
        },
        {
          "uri": "http://www.edamam.com/ontologies/edamam.owl#Measure_ounce",
          "label": "Ounce"
        },
        {
          "uri": "http://www.edamam.com/ontologies/edamam.owl#Measure_pound",
          "label": "Pound"
        },
        {
          "uri": "http://www.edamam.com/ontologies/edamam.owl#Measure_kilogram",
          "label": "Kilogram"
        },
        {
          "uri": "http://www.edamam.com/ontologies/edamam.owl#Measure_cup",
          "label": "Cup"
        }

文件继续。

我尝试做 [String] 但它说它需要一个字典, 所以我放了一本字典,然后它说它需要另一本字典, 重复直到我得到这个:

let posts = try! JSONDecoder().decode([String: [String: [String: String]]].self, from: data!)

然后我得到错误

"Expected to decode Dictionary<String, Any> but found a string/data instead.", underlyingError: nil))

虽然当我回去做一个 string/data 我得到这个错误

"Expected to decode String but found a dictionary instead.", underlyingError: nil))

帮忙?

如评论中所述,您可以使用 quick parser,但是 您需要了解为什么会发生这种情况,这里的问题是您传递的 [String: [String: [String: String]]] 不是此密钥的有效骨架 您可以开始单独分解每一层以了解第一级,例如 [String, Any]然后开始导出每个密钥并单独解码,使用上面的 link 你的模型应该是这样的。

// MARK: - Foo
struct Foo: Codable {
    let text: String
    let parsed: [Parsed]
    let hints: [Hint]
}

// MARK: - Hint
struct Hint: Codable {
    let food: Food
    let measures: [Measure]
}

// MARK: - Food
struct Food: Codable {
    let foodID, label: String
    let nutrients: Nutrients
    let category, categoryLabel: String
    let image: String

    enum CodingKeys: String, CodingKey {
        case foodID = "foodId"
        case label, nutrients, category, categoryLabel, image
    }
}

// MARK: - Nutrients
struct Nutrients: Codable {
    let enercKcal: Int
    let procnt, fat, chocdf, fibtg: Double

    enum CodingKeys: String, CodingKey {
        case enercKcal = "ENERC_KCAL"
        case procnt = "PROCNT"
        case fat = "FAT"
        case chocdf = "CHOCDF"
        case fibtg = "FIBTG"
    }
}

// MARK: - Measure
struct Measure: Codable {
    let uri: String
    let label: String
    let qualified: [Qualified]?
}

// MARK: - Qualified
struct Qualified: Codable {
    let qualifiers: [Qualifier]
}

// MARK: - Qualifier
struct Qualifier: Codable {
    let uri: String
    let label: String
}

// MARK: - Parsed
struct Parsed: Codable {
    let food: Food
}

您可以像这样简单地使用它:

let foo = try? newJSONDecoder().decode(Foo.self, from: jsonData)