Swift Codable:具有字典的数组的数组

时间:2019-04-23 10:56:22

标签: json swift codable jsondecoder

我有一个JSON对象,我无法弄清楚如何访问给定JSON中的exclude_list

{"variants":
    {"variant_groups":
            [
                    {
                        "group_id":"1",
                        "name":"Crust",
                        "variations":[
                            {"name":"Thin","price":0,"default":1,"id":"1","inStock":1},
                            {"name":"Thick","price":0,"default":0,"id":"2","inStock":1,"isVeg":1},
                            {"name":"Cheese burst","price":100,"default":0,"id":"3","inStock":1,"isVeg":1}]},

                    {
                        "group_id":"3",
                        "name":"Sauce",
                        "variations":[
                            {"name":"Manchurian","price":20,"default":0,"id":"20","inStock":1,"isVeg":0},
                            {"name":"Tomato","price":20,"default":0,"id":"21","inStock":1,"isVeg":1},
                            {"name":"Mustard","price":20,"default":0,"id":"22","inStock":1,"isVeg":0}]

                    }],
            "exclude_list":[
                [
                    {"group_id":"1","variation_id":"3"},
                    {"group_id":"2","variation_id":"10"}
                ],
                [
                    {"group_id":"2","variation_id":"10"},
                    {"group_id":"3","variation_id":"22"}
                ]
            ]
    }
}

我可以使用下面的variants访问以下属性:variant_groupsStruct

public struct VariantResponse: Codable {

    public let variants: Variants
}
public struct Variants: Codable {

    public let variantGroups:[VariantGroup]
    public let excludeList:[ExcludeItems]
}
public struct VariantGroup: Codable {
    public let groupId: String
    public let name: String
    public let variations: [Variant]
}
public struct Variant: Codable {
    public let name: String
    public let price: Int
    public let defaultValue: Int
    public let id: String
    public let inStock: Int
    public var isVeg: Int?

    private enum CodingKeys : String, CodingKey {
        case name, price, defaultValue = "default", id, inStock, isVeg
    }    
}
public struct ExcludeItems: Codable {
    public let excludes:[Exclude]
}
public struct Exclude: Codable {
    public let groupId: String
    public let variationId: String
}

3 个答案:

答案 0 :(得分:1)

您可以尝试

struct VariantResponse: Codable {
    let variants: Variants
}

struct Variants: Codable {
    let variantGroups: [VariantGroup]
    let excludeList: [[ExcludeItems]]

}

struct ExcludeItems: Codable {
    let groupId, variationId: String

}

do {

    let dec = JSONDecoder()
    dec.keyDecodingStrategy = .convertFromSnakeCase
    let res = try dec.decode(VariantResponse.self, from: data)

}
catch {

    print(error)
}

ExcludeItems包含groupId, variationId,但是您添加了未知密钥excludes

答案 1 :(得分:0)

您在可解码的结构中遇到了一些问题,请尝试使用此代码:

    public struct VariantResponse: Codable {
    public let variants: Variants
}

public struct Variants: Codable {
    public let variant_groups:[VariantGroup]
    public let exclude_list:[[Exclude]]
}

public struct VariantGroup: Codable {
    public let group_id: String
    public let name: String
    public let variations: [Variant]
}

public struct Variant: Codable {
    public let name: String
    public let price: Int
    public let defaultValue: Int
    public let id: String
    public let inStock: Int
    public var isVeg: Int?

    private enum CodingKeys : String, CodingKey {
        case name, price, defaultValue = "default", id, inStock, isVeg
    }
}

public struct Exclude: Codable {
    public let group_id: String
    public let variation_id: String
}

祝你好运。

enter image description here

答案 2 :(得分:0)

问题可能出在模型中的编码键上。请参考以下模型以获取JSON结构。

struct VariantsResponse: Codable {
    let variants: Variants?
}

typealias VariantGroups = [VariantGroup]
typealias ExcludeLists = [[ExcludeList]]
typealias Variations = [Variation]

struct Variants: Codable {
    let variantGroups: VariantGroups?
    let excludeList: ExcludeLists?

    enum CodingKeys: String, CodingKey {
        case variantGroups = "variant_groups"
        case excludeList = "exclude_list"
    }
}

struct ExcludeList: Codable {
    let groupId, variationId: String?

    enum CodingKeys: String, CodingKey {
        case groupId = "group_id"
        case variationId = "variation_id"
    }
}

struct VariantGroup: Codable {
    let groupId, name: String?
    let variations: Variations?

    enum CodingKeys: String, CodingKey {
        case groupId = "group_id"
        case name, variations
    }
}

struct Variation: Codable {
    let name: String?
    let price, variationDefault: Int?
    let id: String?
    let inStock, isVeg: Int?

    enum CodingKeys: String, CodingKey {
        case name, price
        case variationDefault = "default"
        case id, inStock, isVeg
    }
}

在上面的模型中,我为以下数组创建类型别名,以使模型更易于理解和理解。

typealias VariantGroups = [VariantGroup]
typealias ExcludeLists = [[ExcludeList]]
typealias Variations = [Variation]

在这里,我们为不能直接转换为模型属性的变量定义了encodingKeys大小写。

希望这将帮助您创建模型。

您可以使用以下代码简单地使用responseData解码模型

let decoder = JSONDecoder()
let res = try decoder.decode(VariantsResponse.self, from: responseData)

在这里,如果我们指定decoder.keyDecodingStrategy = .convertFromSnakeCase,则不需要指定诸如case groupId = "group_id"之类的编码键。系统将自动检查_字符并将JSON密钥字符串转换为camelCaseKeys。