首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >快速解码错误-解码JSON时找不到密钥

快速解码错误-解码JSON时找不到密钥
EN

Stack Overflow用户
提问于 2022-04-15 18:17:31
回答 2查看 409关注 0票数 0

我正在我的Swift应用程序中解码一个JSON响应,当我切换api URL时,代码决定不工作。

这是我的json回应

代码语言:javascript
运行
复制
   {
   "totalHits":396990,
   "currentPage":1,
   "totalPages":396990,
   "pageList":[
      1,
      2,
      3,
      4,
      5,
      6,
      7,
      8,
      9,
      10
   ],
   "foodSearchCriteria":{
      "dataType":[
         
      ],
      "pageNumber":1,
      "numberOfResultsPerPage":50,
      "pageSize":1,
      "requireAllWords":false
   },
   "foods":[
      {
         "fdcId":1104067,
         "description":"100 GRAND Bar",
         "lowercaseDescription":"100 grand bar",
         "commonNames":"",
         "additionalDescriptions":"$ 100,000 Bar",
         "dataType":"Survey (FNDDS)",
         "foodCode":91715300,
         "publishedDate":"2020-10-30",
         "foodCategory":"Candy containing chocolate",
         "foodCategoryId":999786,
         "allHighlightFields":"",
         "score":1.0,
         "foodNutrients":[
            {
               "nutrientId":1003,
               "nutrientName":"Protein",
               "nutrientNumber":"203",
               "unitName":"G",
               "value":2.5,
               "rank":600,
               "indentLevel":1,
               "foodNutrientId":13301423
            },
   
            {
               "nutrientId":1280,
               "nutrientName":"PUFA 22:5 n-3 (DPA)",
               "nutrientNumber":"631",
               "unitName":"G",
               "value":0.0,
               "rank":15200,
               "indentLevel":2,
               "foodNutrientId":13301485
            },
            {
               "nutrientId":1292,
               "nutrientName":"Fatty acids, total monounsaturated",
               "nutrientNumber":"645",
               "unitName":"G",
               "value":6.04,
               "rank":11400,
               "indentLevel":1,
               "foodNutrientId":13301486
            },
            {
               "nutrientId":1293,
               "nutrientName":"Fatty acids, total polyunsaturated",
               "nutrientNumber":"646",
               "unitName":"G",
               "value":1.39,
               "rank":12900,
               "indentLevel":1,
               "foodNutrientId":13301487
            }
         ],
         "finalFoodInputFoods":[
            {
               "foodDescription":"Candies, NESTLE, 100 GRAND Bar",
               "gramWeight":100,
               "id":102104,
               "portionCode":"0",
               "portionDescription":"NONE",
               "unit":"GM",
               "rank":1,
               "srCode":19144,
               "value":100
            }
         ],
         "foodMeasures":[
            {
               "disseminationText":"1 bar (1.5 oz)",
               "gramWeight":43,
               "id":246540,
               "modifier":"60362",
               "rank":1,
               "measureUnitAbbreviation":"undetermined",
               "measureUnitName":"undetermined",
               "measureUnitId":9999
            },
            {
               "disseminationText":"Quantity not specified",
               "gramWeight":21,
               "id":266827,
               "modifier":"90000",
               "rank":2,
               "measureUnitAbbreviation":"undetermined",
               "measureUnitName":"undetermined",
               "measureUnitId":9999
            }
         ],
         "foodAttributes":[
            
         ],
         "foodAttributeTypes":[
            {
               "name":"Additional Description",
               "description":"Additional descriptions for the food.",
               "id":1001,
               "foodAttributes":[
                  {
                     "value":"$ 100,000 Bar",
                     "id":978293,
                     "sequenceNumber":1
                  }
               ]
            },
            {
               "name":"Attribute",
               "description":"Generic attributes",
               "id":999,
               "foodAttributes":[
                  {
                     "value":"5702",
                     "name":"WWEIA Category number",
                     "id":991595
                  },
                  {
                     "value":"Candy containing chocolate",
                     "name":"WWEIA Category description",
                     "id":999786
                  }
               ]
            }
         ],
         "foodVersionIds":[
            
         ]
      }
   ],
   "aggregations":{
      "dataType":

我正面临着这个错误

代码语言:javascript
运行
复制
Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "foods", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"foods\", intValue: nil) (\"foods\").", underlyingError: nil))

我想这是因为我的“食物”没有正确匹配,但看起来并不是这样。下面我附加了我的调用和结构的片段。

代码语言:javascript
运行
复制
  struct APISearchResults: Codable {
    let currentPage, totalPages: Int?
    let pageList: [Int]?
    //let foodSearchCriteria: FoodSearchCriteria
    let foods: [Food]
    
}


// MARK: - Food
struct Food: Codable { //core
    let fdcID: Int
    let foodDescription, lowercaseDescription, commonNames, additionalDescriptions: String?
    let dataType: String?
    let ndbNumber: Int?
    let publishedDate, foodCategory, allHighlightFields: String?
    let score: Double?
    let foodNutrients: [FoodNutrientInformation]
    let gtinUpc: Double?
    let brandOwner: String?
    let ingredients: String?
    let marketCountry: String?
    let modifiedDate: String?
    let dataSource: String?
    let servingSize: Double?
    let householdServingFullText: String?
    
    
    enum CodingKeys: String, CodingKey {
        case fdcID = "fdcId"
        case foodDescription = "description"
        case lowercaseDescription, commonNames, additionalDescriptions, dataType, ndbNumber, publishedDate, foodCategory, allHighlightFields, score, foodNutrients, gtinUpc, brandOwner, ingredients, marketCountry, modifiedDate, dataSource, servingSize, householdServingFullText
    }
}

// MARK: - FoodNutrient
struct FoodNutrientInformation: Codable {
    let nutrientID: Int?
    let nutrientName, nutrientNumber, unitName, derivationCode: String
    let derivationDescription: String?
    let derivationID: Int?
    let value: Double?
    let foodNutrientSourceID: Int?
    let foodNutrientSourceCode, foodNutrientSourceDescription: String?
    let rank, indentLevel, foodNutrientID, dataPoints: Int?

    enum CodingKeys: String, CodingKey {
        case nutrientID = "nutrientId"
        case nutrientName, nutrientNumber, unitName, derivationCode, derivationDescription
        case derivationID = "derivationId"
        case value
        case foodNutrientSourceID = "foodNutrientSourceId"
        case foodNutrientSourceCode, foodNutrientSourceDescription, rank, indentLevel
        case foodNutrientID = "foodNutrientId"
        case dataPoints
    }
}

为了详细起见,我还会附上API调用本身,以防它与此相关。

代码语言:javascript
运行
复制
class FoodApiSearch: ObservableObject{
    @Published var foodDescription = ""
    @Published var foodUnit = ""
    @Published var calories = ""
    
    //will search for user Input
    func searchFood(userItem: String){
       //calls api search
        guard let url = URL(string: "https://api.nal.usda.gov/fdc/v1/foods/search?api_key=***********?query=\(userItem)") else {return}
        
        URLSession.shared.dataTask(with: url) { (data, _,_) in
            let searchResults = try! JSONDecoder().decode(APISearchResults.self, from: data!)
            
            DispatchQueue.main.async {
                for item in searchResults.foods{
                    self.foodDescription = item.lowercaseDescription?.firstCapitalized ?? "food not valid"
                    self.calories = String(Double(round(item.foodNutrients[3].value!)).removeZerosFromEnd())
 
                   
                    }
               
                }
        }
        .resume()
    }
}
EN

回答 2

Stack Overflow用户

发布于 2022-04-15 18:45:08

如果您有未解码的额外变量,则需要包含一个codingKeys枚举,其中只需要解码所需的JSON。你的可编码应该是:

代码语言:javascript
运行
复制
struct APISearchResults: Codable {
    var currentPage, totalPages: Int?
    var pageList: [Int]?
    //let foodSearchCriteria: FoodSearchCriteria
    let foods: [Food]

    enum CodingKeys: String, CodingKey {
        case foods
    }
}

解码器正在寻找不存在于JSON中的currentPagetotalPagespageList。当您不包括您自己的codingKeys时,编译器会合成它们,所以在本例中您必须显式地定义它们。

票数 0
EN

Stack Overflow用户

发布于 2022-04-16 08:43:31

基于您显示的json数据,下面的结构模型对我有效。下面是我在测试中使用的代码:

编辑-1:给定提供的“新”json数据,更改了FoodNutrient

代码语言:javascript
运行
复制
struct Food: Codable {
    let fdcID: Int
    let foodDescription, lowercaseDescription, commonNames, additionalDescriptions: String?
    let dataType: String?
    let ndbNumber: Int?
    let publishedDate, foodCategory, allHighlightFields: String?
    let score: Double?
    let foodNutrients: [FoodNutrient]?  // <-- here optional
    let gtinUpc: String?   // <-- here not Double
    let brandOwner: String?
    let ingredients: String?
    let marketCountry: String?
    let modifiedDate: String?
    let dataSource: String?
    let servingSize: Double?
    let householdServingFullText: String?
    
    enum CodingKeys: String, CodingKey {
        case fdcID = "fdcId"
        case foodDescription = "description"
        case lowercaseDescription, commonNames, additionalDescriptions, dataType, ndbNumber, publishedDate, foodCategory, allHighlightFields, score, gtinUpc, foodNutrients, brandOwner, ingredients, marketCountry, modifiedDate, dataSource, servingSize, householdServingFullText
    }
}

    struct FoodNutrient: Codable {
    let nutrientID: Int?
    let nutrientName, nutrientNumber, unitName: String
    let value: Double?
    let rank, indentLevel, foodNutrientID: Int?

    enum CodingKeys: String, CodingKey {
        case nutrientID = "nutrientId"
        case nutrientName, nutrientNumber, unitName, value, rank, indentLevel
        case foodNutrientID = "foodNutrientId"
    }
}

struct APISearchResults: Codable {
    var currentPage, totalPages: Int?  // <-- here
    var pageList: [Int]?  // <-- here
    let foods: [Food]
}

struct ContentView: View {
    var body: some View {
        Text("testing")
            .onAppear {

        let json = """
   {
   "totalHits":396990,
   "currentPage":1,
   "totalPages":396990,
   "pageList":[
      1,
      2,
      3,
      4,
      5,
      6,
      7,
      8,
      9,
      10
   ],
   "foodSearchCriteria":{
      "dataType":[ ],
      "pageNumber":1,
      "numberOfResultsPerPage":50,
      "pageSize":1,
      "requireAllWords":false
   },
   "foods":[
      {
         "fdcId":1104067,
         "description":"100 GRAND Bar",
         "lowercaseDescription":"100 grand bar",
         "commonNames":"",
         "additionalDescriptions":"$ 100,000 Bar",
         "dataType":"Survey (FNDDS)",
         "foodCode":91715300,
         "publishedDate":"2020-10-30",
         "foodCategory":"Candy containing chocolate",
         "foodCategoryId":999786,
         "allHighlightFields":"",
         "score":1.0,
         "foodNutrients":[
            {
               "nutrientId":1003,
               "nutrientName":"Protein",
               "nutrientNumber":"203",
               "unitName":"G",
               "value":2.5,
               "rank":600,
               "indentLevel":1,
               "foodNutrientId":13301423
            },
            {
               "nutrientId":1280,
               "nutrientName":"PUFA 22:5 n-3 (DPA)",
               "nutrientNumber":"631",
               "unitName":"G",
               "value":0.0,
               "rank":15200,
               "indentLevel":2,
               "foodNutrientId":13301485
            },
            {
               "nutrientId":1292,
               "nutrientName":"Fatty acids, total monounsaturated",
               "nutrientNumber":"645",
               "unitName":"G",
               "value":6.04,
               "rank":11400,
               "indentLevel":1,
               "foodNutrientId":13301486
            },
            {
               "nutrientId":1293,
               "nutrientName":"Fatty acids, total polyunsaturated",
               "nutrientNumber":"646",
               "unitName":"G",
               "value":1.39,
               "rank":12900,
               "indentLevel":1,
               "foodNutrientId":13301487
            }
         ],
         "finalFoodInputFoods":[
            {
               "foodDescription":"Candies, NESTLE, 100 GRAND Bar",
               "gramWeight":100,
               "id":102104,
               "portionCode":"0",
               "portionDescription":"NONE",
               "unit":"GM",
               "rank":1,
               "srCode":19144,
               "value":100
            }
         ],
         "foodMeasures":[
            {
               "disseminationText":"1 bar (1.5 oz)",
               "gramWeight":43,
               "id":246540,
               "modifier":"60362",
               "rank":1,
               "measureUnitAbbreviation":"undetermined",
               "measureUnitName":"undetermined",
               "measureUnitId":9999
            },
            {
               "disseminationText":"Quantity not specified",
               "gramWeight":21,
               "id":266827,
               "modifier":"90000",
               "rank":2,
               "measureUnitAbbreviation":"undetermined",
               "measureUnitName":"undetermined",
               "measureUnitId":9999
            }
         ],
         "foodAttributes":[ ],
         "foodAttributeTypes":[
            {
               "name":"Additional Description",
               "description":"Additional descriptions for the food.",
               "id":1001,
               "foodAttributes":[
                  {
                     "value":"$ 100,000 Bar",
                     "id":978293,
                     "sequenceNumber":1
                  }
               ]
            },
            {
               "name":"Attribute",
               "description":"Generic attributes",
               "id":999,
               "foodAttributes":[
                  {
                     "value":"5702",
                     "name":"WWEIA Category number",
                     "id":991595
                  },
                  {
                     "value":"Candy containing chocolate",
                     "name":"WWEIA Category description",
                     "id":999786
                  }
               ]
            }
         ],
         "foodVersionIds":[ ]
      }
   ]
}
"""
                let data = json.data(using: .utf8)!
                do {
                    let searchResults = try JSONDecoder().decode(APISearchResults.self, from: data)
                    print("\n ---> searchResults:\n \(searchResults) \n")
                } catch {
                    print("\n---> ERROR \(error) \n")
                }
            }
    }
}

注意:“新”json数据是不正确的,结束"aggregations":{ "dataType":缺少一些部分。

print(String(data: data!, encoding: .utf8))之前添加let searchResults = try! JSONDecoder()....,并向我们展示它真正打印的内容,而不是显示您认为响应给您带来的一些json。那就很容易帮你解决你的解码问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71887521

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档