使用swift 4中的codable解析嵌套数组

时间:2017-12-25 20:39:00

标签: ios swift4 xcode9 codable jsonparser

我收到很多随机问题。大多数情况下,某些结构无法解码,无法理解如何定义结构。

请找到代码剪切

var 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":"2","name":"Size","variations":[{"name":"Small","price":0,"default":1,"id":"10","inStock":1,"isVeg":0},{"name":"Medium","price":100,"default":0,"id":"11","inStock":1,"isVeg":1},{"name":":Large","price":200,"default":0,"id":"12","inStock":1,"isVeg":0}]},{"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"}]]}}
""".data(using: .utf8)

/* 
 not sure is this the right way to define Root
*/
    struct Root : Codable {

        let variants : varientStruct
        let exclude_list : exclude_list

    }

    struct exclude_list : Codable{
        let variation_id : String
        let group_id : String
    }

    struct varientStruct: Codable {
        let variant_groups = [variant_groups_struct]
    }
    struct variant_groups_struct : Codable {
        let group_id : String
        let name :String
        let variations: [variationsStruct]
    }

    struct variationsStruct :Codable {
        let name : String
        let price : Int
        let selected: Int
        let id : String
        let inStock: Bool

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

do {
    let data = Data(person.utf8)
    let result = try JSONDecoder().decode(Root.self, from: JSON)
    print(result)
} catch  {
    print(error)
}

1 个答案:

答案 0 :(得分:5)

首先,请再次遵循命名惯例:

  • structclass名称以大写字母开头。
  • 变量和函数名称以小写字母开头。
  • 所有变量和struct / class名称都是 camelCased 而不是 snake_cased

其次,JSON非常容易阅读。只有两种集合类型(数组[]和字典{})和四种值类型。

格式化JSON字符串以便更方便地识别结构

let jsonString = """
{"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":"2","name":"Size","variations":
                                    [{"name":"Small","price":0,"default":1,"id":"10","inStock":1,"isVeg":0},
                                    {"name":"Medium","price":100,"default":0,"id":"11","inStock":1,"isVeg":1},
                                    {"name":":Large","price":200,"default":0,"id":"12","inStock":1,"isVeg":0}]
                                },{"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"}]]
            }
}
"""

然后按照JSON结构逐步构建结构

struct Root : Decodable {
    let variants : Variant
}

struct Variant : Decodable {

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

    let groups : [VariantGroup]
    let excludeList : [[ExcludeList]]
}

struct VariantGroup : Decodable {

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

    let groupID : String
    let name : String
    let variations : [Variation]
}

struct Variation  : Decodable {

    let name : String
    let price : Int
    let `default` : Int
    let id : String
    let inStock : Int
}


struct ExcludeList : Decodable {
    private enum CodingKeys : String, CodingKey {
        case groupID = "group_id"
        case variationID = "variation_id"
    }

    let groupID : String
    let variationID : String
}

然后解码东西

do { 
   let data = Data(jsonString.utf8)      
   let result = try JSONDecoder().decode(Root.self, from: data)
   print(result)

} catch { print(error) }