Swift Codable: массив массивов со словарями - PullRequest
0 голосов
/ 23 апреля 2019

У меня есть объект JSON, я не могу понять, как получить доступ к exclude_list в данном JSON.

{"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_groups, используя ниже Struct:

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 ]

1 голос
/ 23 апреля 2019

Вы можете попробовать

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

0 голосов
/ 27 апреля 2019

Возможно, проблема связана с ключами кодирования в вашей модели.Пожалуйста, обратитесь к следующей модели для получения вашей структуры 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 для следующих массивов, чтобы сделать модель более удобочитаемой и понятной для человека.

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

здесь мы определяем регистр codingKeys для переменных, которые не могут напрямую преобразовываться в атрибут модели.

Надеюсь, это поможет вам создать модель.

Вы можете просто декодировать модель с помощью responseData, используя следующий код

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

Здесь, если мы указываем decoder.keyDecodingStrategy = .convertFromSnakeCase, нам не нужно было указывать codingKeys, например case groupId = "group_id".Система автоматически проверит символ _ и преобразует строку ключа JSON в camelCaseKeys.

0 голосов
/ 23 апреля 2019

у вас есть проблемы с декодируемыми структурами, попробуйте использовать этот код:

    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

...