Swift 4 Decodable - 没有与键 CodingKeys 关联的值 [重复]
Posted
技术标签:
【中文标题】Swift 4 Decodable - 没有与键 CodingKeys 关联的值 [重复]【英文标题】:Swift 4 Decodable - No value associated with key CodingKeys [duplicate] 【发布时间】:2019-08-28 22:38:18 【问题描述】:我正在我的 Swift 应用程序中解码 JSON 响应,并且代码在它决定停止工作之前一直有效。
这是我的 json 回复
"foods": [
"food_name": "Milk Chocolate",
"brand_name": "Snickers",
"serving_weight_grams": 41.7,
"nf_calories": 212.3,
"nf_total_fat": 11.6,
"nf_saturated_fat": 4,
"nf_total_carbohydrate": 22.7,
"nf_protein": 3.9
]
这是解码我的 json 的代码
let task = URLSession.shared.dataTask(with: request) (data, response, error) in
guard let data = data else return
print(String(data: data, encoding: .utf8)!)
do
//Decode dataResponse received from a network request
let decoder = JSONDecoder()
let foods = try decoder.decode(JSONFoods.self, from: data) //Decode JSON Response Data
self.jsonfood = foods.JSONFood[0]
print(self.jsonfood!)
catch let parsingError
print("Error", parsingError)
task.resume()
我的结构是
struct JSONFoods: Decodable
var JSONFood: [JSONFood]
struct JSONFood: Decodable
var food_name: String
var brand_name: String
var nf_calories: Int
var nf_protein: Int
var nf_total_fat: Int
var nf_total_carbohydrate: Int
var serving_weight_grams: Int
我得到的错误信息是这样的
keyNotFound(CodingKeys(stringValue: "JSONFood", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "没有与键 CodingKeys 关联的值(stringValue: "JSONFood", intValue: nil) ( "JSONFood").", 底层错误:nil))
如果我将 decode(JSONFoods.self, from: data) 替换为 decode(JSONFood.self, from: data) 我收到此错误消息
keyNotFound(CodingKeys(stringValue: "food_name", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "没有与键 CodingKeys 关联的值(stringValue: "food_name", intValue: nil) ( "food_name").", 基础错误:nil))
我到处搜索都没有运气,非常感谢任何帮助
【问题讨论】:
JSONFood
!= foods
.
【参考方案1】:
你需要
struct Root: Codable
let foods: [Food]
struct Food: Codable
let foodName: String?
let brandName: String
let servingWeightGrams, nfCalories, nfTotalFat: Double
let nfSaturatedFat: Int
let nfTotalCarbohydrate, nfProtein: Double
enum CodingKeys: String, CodingKey
case foodName = "food_name"
case brandName = "brand_name"
case servingWeightGrams = "serving_weight_grams"
case nfCalories = "nf_calories"
case nfTotalFat = "nf_total_fat"
case nfSaturatedFat = "nf_saturated_fat"
case nfTotalCarbohydrate = "nf_total_carbohydrate"
case nfProtein = "nf_protein"
首先:你应该是JSONFood
,而它应该是foods
第二个:food_name
在当前的 json 根目录中不存在,所以这会失败
let foods = try decoder.decode(JSONFoods.self, from: data) //Decode JSON Response Data
万一利用convertFromSnakeCase
let str = """
"foods":["food_name":"Milk Chocolate","brand_name":"Snickers","serving_weight_grams":41.7,"nf_calories":212.3,"nf_total_fat":11.6,"nf_saturated_fat":4,"nf_total_carbohydrate":22.7,"nf_protein":3.9]
"""
do
let res = JSONDecoder()
res.keyDecodingStrategy = .convertFromSnakeCase
let ss = try res.decode(Root.self, from:Data(str.utf8))
print(ss)
catch
print(error)
struct Root: Codable
let foods: [Food]
struct Food: Codable
let foodName: String?
let brandName: String
let servingWeightGrams, nfCalories, nfTotalFat: Double
let nfSaturatedFat: Int
let nfTotalCarbohydrate, nfProtein: Double
【讨论】:
不需要将JSONFoods
结构重命名为Root
。
我会这样做,以防有多个结构用于突出显示基本模型
出现问题中的第二个错误是因为 OP 将子结构 JSONFood
解码为根对象。 food_name
可能丢失与此无关。为什么不建议.convertFromSnakeCase
策略来摆脱CodingKeys
?
我只是在评论之前编辑它:),是的,我同意蛇案例更好,但动态站点生成现在可能不会考虑它=D以上是关于Swift 4 Decodable - 没有与键 CodingKeys 关联的值 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
Swift 4 Decodable - 将 JSON 对象解码为“数据”
Swift 4 Decodable:给定的数据不是有效的 JSON
在 Swift 4 中使用 Decodable 解析 JSON