首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Swift解码器协议解码JSON时出现问题

使用Swift解码器协议解码JSON时出现问题
EN

Stack Overflow用户
提问于 2020-06-04 00:08:15
回答 1查看 65关注 0票数 0

我正在尝试使用Swift解码器协议来解析一些JSON,但是我得到了一些我无法理解的错误。我要返回的JSON是有问题的,因为并不是所有的键都肯定存在,所以我给出了相应结构的属性默认值并设置了一个初始化器,但我怀疑我的方法是错误的。

在"foods“数组中,一些项具有属性"ndbNumber”(字符串),另一些项具有fdcId (Int)和gtinUpc (字符串)属性。否则,这些项是相同的,并且表示从搜索返回的食品项。

这是最外层的JSON级别的结构。

代码语言:javascript
复制
public struct ReturnedFoods: Decodable {
    public let count: Int
    public let all: [ReturnedFood]

    enum CodingKeys: String, CodingKey {
        case count = "totalHits"
        case all = "foods"
    }
}

这是下一级的食物项目:

代码语言:javascript
复制
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非常长,所以我只发布其中的一小部分:

代码语言:javascript
复制
  "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

如果能帮我解决这个问题,我将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2020-06-04 00:16:23

foodsndbNumber的类型不匹配,请使用此结构进行解码:

代码语言:javascript
复制
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"
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62177471

复制
相关文章

相似问题

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