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 做这样的事情很简单,就像这个答案对Codable
s 所做的一样。但我想知道是否只能使用 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 将 POST 请求中的 JSON 数据保存到字典中?