Swifty JSON:将JSON数组中对象的分层列表转换为分层Swift对象

时间:2019-05-22 08:34:16

标签: json swift swift4 hierarchical-data swifty-json

我有一个下面的JSON格式,它属于这个json对象内的一家商店,Data字段是一个JSON数组,其中包含产品类别的层次结构,这些类别以嵌套的层次结构格式存储(每个类别都有个孩子,每个孩子都可以有自己的孩子,等等。

{"Data":[
            {"ID":1,"ParentCategoryId":0,"Name": "Parent1","Children":
                [
                    {"ID":2,"ParentCategoryId":1,"Name": "P1Child1","Children":[]},
                    {"ID":3,"ParentCategoryId":1,"Name": "P1Child2","Children":[]},
                    {"ID":4,"ParentCategoryId":1,"Name": "P1Child3","Children":[]},
                    {"ID":5,"ParentCategoryId":1,"Name": "P1Child4","Children":[]},
                ]
            },
            {"ID":6,"ParentCategoryId":0,"Name": "Parent2","Children":
                [
                    {"ID":7,"ParentCategoryId":6,"Name": "P2Child1","Children":[]},
                    {"ID":8,"ParentCategoryId":6,"Name": "P2Child2","Children":[]},
                    {"ID":9,"ParentCategoryId":6,"Name": "P2Child3","Children":[]}
                ]
            }
        ]
}

使用Swifty JSON usign json["Data"].array读取此格式将返回没有层次结构的类别的平面列表。 我想知道如何在保留其结构的同时读取此分层JSON对象。 这是我的模型对象的当前结构(不包括子项,但必须对其进行修改):

open class ProductCategory: NSObject {


    var idd                 :  NSInteger
    var name                :  String
    var parentCategoryId    :  NSInteger
    ...

}

3 个答案:

答案 0 :(得分:0)

在这里,您可以使用Codable

对此建模
struct MyData: Codable {
    let data: [Datum]

    enum CodingKeys: String, CodingKey {
        case data = "Data"
    }
}

struct Datum: Codable {
    let id, parentCategoryID: Int
    let name: String
    let children: [Datum]

    enum CodingKeys: String, CodingKey {
        case id = "ID"
        case parentCategoryID = "ParentCategoryId"
        case name = "Name"
        case children = "Children"
    }
}

do {
    let myData = try JSONDecoder().decode(MyData.self, from: yourJsonData)
} catch {
    print(error)
}

答案 1 :(得分:0)

如果您可以考虑从swiftyjson转到JSONSerialization,则以下内容应为您提供所需的结构

do {
    if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
        if let categories = json["Data"] as? [[String: Any]] {            
          //map data to your classes here
        }
    }
} catch {
    print("Decode failed: \(error)")
}

答案 2 :(得分:-1)

如果您使用Codable,则不需要SwiftyJSON,您可以这样做:

        do {
            let productsData = try JSONDecoder().decode(ProductsDataResponse.self, from: (jsonString.data(using: .utf8))!)
        } catch let e {
            print("Couldn't Parse data because... \(e)")
        }

ProductsDataResponse在哪里:

struct ProductsDataResponse: Codable {
    let data: [ProductCategory]

    enum CodingKeys: String, CodingKey {
        case data = "Data"
    }
}