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

Posted

技术标签:

【中文标题】Swifty JSON:将 JSON 数组中的对象分层列表转换为分层 Swift 对象【英文标题】:Swifty JSON: convert hierarchical list of objects in JSON arrays to hierarchical Swift objects 【发布时间】:2019-05-22 08:34:16 【问题描述】:

我有一个下面的 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 ussign json["Data"].array 读取此格式会返回一个没有层次结构的类别的平面列表。 我想知道如何在保留其结构的同时读取此分层 JSON 对象。 这是我的模型对象的当前结构(不包括 Children 归档,但必须修改为这样):

open class ProductCategory: NSObject 


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


【问题讨论】:

【参考方案1】:

这是使用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)

【讨论】:

@VSB 这种方法有什么问题?您究竟想如何设计模型? @PGDev 我的方法没有问题。 -1 不是我的!但我仍在寻找其他可能的答案,这些答案需要对我的代码库进行较少的更改。 @VSB 你的“代码库”是什么?您能否改进/澄清您的问题,以便我们更好地了解您希望从解决方案中获得什么? @JoakimDanielson 我的 API 调用中的响应由 Swifty JSON 解析,模型基于此场景。我不想重写我的所有请求/响应以使它们适合 Codable 并摆脱 Swifty JSON。我不知道这是否是一个好的偏好,因为我是 ios 和 Swift 的新手,但是在 android 环境中使用 Retrofit 和 GSON 做这样的事情很简单,就像这个答案对Codables 所做的一样。但我想知道是否只能使用 Swifty JSON。 最好开始使用Codable 而不是第三方库。它更加高效和可读。【参考方案2】:

如果您可以考虑从 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)")

【讨论】:

【参考方案3】:

如果你使用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"
    

【讨论】:

以上是关于Swifty JSON:将 JSON 数组中的对象分层列表转换为分层 Swift 对象的主要内容,如果未能解决你的问题,请参考以下文章

使用 Swifty JSON 解析数组

如何使用 Swifty Json 将 POST 请求中的 JSON 数据保存到字典中?

Swifty JSON 响应解析

如何使用 Swifty 动态创建具有多个键和值的 json 对象

如何使用 Swifty JSON 连接两个 json 对象

你能用 Swifty-JSON 搜索 JSON 吗?