我正在尝试使用Swift解码器协议来解析一些JSON,但是我得到了一些我无法理解的错误。我要返回的JSON是有问题的,因为并不是所有的键都肯定存在,所以我给出了相应结构的属性默认值并设置了一个初始化器,但我怀疑我的方法是错误的。
在"foods“数组中,一些项具有属性"ndbNumber”(字符串),另一些项具有fdcId (Int)和gtinUpc (字符串)属性。否则,这些项是相同的,并且表示从搜索返回的食品项。
这是最外层的JSON级别的结构。
public struct ReturnedFoods: Decodable {
public let count: Int
public let all: [ReturnedFood]
enum CodingKeys: String, CodingKey {
case count = "totalHits"
case all = "foods"
}
}这是下一级的食物项目:
public struct ReturnedFood: Codable {
public var ndbNumber: String = ""
public var fdcId : Int = -1
public var description: String = ""
public var dataType : String = ""
public var brandOwner: String = ""
public var gtinUpc : String = ""
public var ingredients : String = ""
public var publishedDate : String = ""
public var score : Float = -1
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
if let ndbNumber = try values.decodeIfPresent(String.self, forKey: .ndbNumber) {
self.ndbNumber = ndbNumber
}
if let fdcId = try values.decodeIfPresent(Int.self, forKey: .ndbNumber) {
self.fdcId = fdcId
}
if let description = try values.decodeIfPresent(String.self, forKey: .description) {
self.description = description
}
if let dataType = try values.decodeIfPresent(String.self, forKey: .dataType) {
self.dataType = dataType
}
if let brandOwner = try values.decodeIfPresent(String.self, forKey: .brandOwner) {
self.brandOwner = brandOwner
}
if let gtinUpc = try values.decodeIfPresent(String.self, forKey: .gtinUpc) {
self.gtinUpc = gtinUpc
}
if let ingredients = try values.decodeIfPresent(String.self, forKey: .ingredients) {
self.ingredients = ingredients
}
if let publishedDate = try values.decodeIfPresent(String.self, forKey: .publishedDate) {
self.publishedDate = publishedDate
}
if let score = try values.decodeIfPresent(Float.self, forKey: .score) {
self.score = score
}
}
}我已经仔细检查以确保所有类型都是正确的,所以我怀疑问题出在缺少键上。
这是我得到的错误: typeMismatch(Swift.Int,Swift.DecodingError.Context(codingPath: CodingKeys(stringValue:"foods",intValue: nil),_JSONKey(stringValue:“index4”,intValue: 4),CodingKeys(stringValue:"ndbNumber",intValue: nil),debugDescription:“期望解码Int.但找到了字符串/数据。”,underlyingError: nil)
JSON非常长,所以我只发布其中的一小部分:
"foodSearchCriteria": {
"dataType": [
"Foundation",
"Branded"
],
"query": "cheddar",
"generalSearchInput": "cheddar",
"pageNumber": 1,
"requireAllWords": false
},
"totalHits": 12839,
"currentPage": 1,
"totalPages": 257,
"foods": [
{
"fdcId": 566851,
"description": "CHEDDAR",
"dataType": "Branded",
"gtinUpc": "828280001766",
"publishedDate": "2019-04-01",
"brandOwner": "FISCALINI",
"ingredients": "PASTEURIZED COW'S MILK, CHEESE CULTURES, ENZYMES (MICROBIAL RENNET), SALT.",
"foodNutrients": [
{
"nutrientId": 1079,
"nutrientName": "Fiber, total dietary",
"nutrientNumber": "291",
"unitName": "G",
"derivationCode": "LCCD",
"derivationDescription": "Calculated from a daily value percentage per serving size measure",
"value": 0
},
{
"nutrientId": 1087,
"nutrientName": "Calcium, Ca",
"nutrientNumber": "301",
"unitName": "MG",
"derivationCode": "LCCD",
"derivationDescription": "Calculated from a daily value percentage per serving size measure",
"value": 714
},
{
"nutrientId": 1089,
"nutrientName": "Iron, Fe",
"nutrientNumber": "303",
"unitName": "MG",
"derivationCode": "LCCD",
"derivationDescription": "Calculated from a daily value percentage per serving size measure",
"value": 0
},
{
"nutrientId": 1104,
"nutrientName": "Vitamin A, IU",
"nutrientNumber": "318",
"unitName": "IU",
"derivationCode": "LCCD",
"derivationDescription": "Calculated from a daily value percentage per serving size measure",
"value": 1071
},
{
"nutrientId": 1162,
"nutrientName": "Vitamin C, total ascorbic acid",
"nutrientNumber": "401",
"unitName": "MG",
"derivationCode": "LCCD",
"derivationDescription": "Calculated from a daily value percentage per serving size measure",
"value": 0
},
{
"nutrientId": 1003,
"nutrientName": "Protein",
"nutrientNumber": "203",
"unitName": "G",
"derivationCode": "LCCS",
"derivationDescription": "Calculated from value per serving size measure",
"value": 26.79
},
{
"nutrientId": 1004,
"nutrientName": "Total lipid (fat)",
"nutrientNumber": "204",
"unitName": "G",
"derivationCode": "LCCS",
"derivationDescription": "Calculated from value per serving size measure",
"value": 32.14
},
{
"nutrientId": 1005,
"nutrientName": "Carbohydrate, by difference",
"nutrientNumber": "205",
"unitName": "G",
"derivationCode": "LCCS",
"derivationDescription": "Calculated from value per serving size measure",
"value": 3.57
},
{
"nutrientId": 1008,
"nutrientName": "Energy",
"nutrientNumber": "208",
"unitName": "KCAL",
"derivationCode": "LCCS",
"derivationDescription": "Calculated from value per serving size measure",
"value": 400
},
{
"nutrientId": 1093,
"nutrientName": "Sodium, Na",
"nutrientNumber": "307",
"unitName": "MG",
"derivationCode": "LCCS",
"derivationDescription": "Calculated from value per serving size measure",
"value": 679
},
{
"nutrientId": 1253,
"nutrientName": "Cholesterol",
"nutrientNumber": "601",
"unitName": "MG",
"derivationCode": "LCCS",
"derivationDescription": "Calculated from value per serving size measure",
"value": 111
},
{
"nutrientId": 1257,
"nutrientName": "Fatty acids, total trans",
"nutrientNumber": "605",
"unitName": "G",
"derivationCode": "LCCS",
"derivationDescription": "Calculated from value per serving size measure",
"value": 1.25
},
{
"nutrientId": 1258,
"nutrientName": "Fatty acids, total saturated",
"nutrientNumber": "606",
"unitName": "G",
"derivationCode": "LCCS",
"derivationDescription": "Calculated from value per serving size measure",
"value": 21.43
}
],
"allHighlightFields": "",
"score": 721.74396这里有一个完整的JSON的链接:https://api.nal.usda.gov/fdc/v1/foods/search?query=cheddar&dataType=Foundation,Branded&api_key=DEMO_KEY
如果能帮我解决这个问题,我将不胜感激。
发布于 2020-06-04 00:16:23
键foods和ndbNumber的类型不匹配,请使用此结构进行解码:
struct ReturnedFoods: Codable {
let foodSearchCriteria: FoodSearchCriteria
let totalHits, currentPage, totalPages: Int
let foods: [Food]
}
struct FoodSearchCriteria: Codable {
let dataType: [String]
let query, generalSearchInput: String
let pageNumber: Int
let requireAllWords: Bool
}
struct Food: Codable {
let fdcID: Int
let description, dataType, gtinUpc, publishedDate: String
let brandOwner, ingredients: String
let foodNutrients: [FoodNutrient]
let allHighlightFields: String
let score: Double
enum CodingKeys: String, CodingKey {
case fdcID = "fdcId"
case description, dataType, gtinUpc, publishedDate, brandOwner, ingredients, foodNutrients, allHighlightFields, score
}
}
struct FoodNutrient: Codable {
let nutrientID: Int
let nutrientName, nutrientNumber, unitName: String
let derivationCode: DerivationCode
let derivationDescription: String
let value: Double
enum CodingKeys: String, CodingKey {
case nutrientID = "nutrientId"
case nutrientName, nutrientNumber, unitName, derivationCode, derivationDescription, value
}
}
enum DerivationCode: String, Codable {
case lccd = "LCCD"
case lccs = "LCCS"
}https://stackoverflow.com/questions/62177471
复制相似问题