Swift中如何解码双层嵌套数组结构的JSON?
解决双层嵌套JSON到自定义结构体的解码问题
没问题,我来帮你搞定这个双层嵌套的JSON解码需求!我们可以通过自定义init(from:)解码器来处理这种非直接匹配的JSON结构,下面是具体的实现步骤和代码:
第一步:定义基础结构体
首先我们需要定义Dog结构体,它很直接,只需要遵循Codable协议即可:
struct Dog: Codable { let name: String }
第二步:为Result实现自定义解码器
核心就是给Result结构体编写自定义的初始化方法,来手动处理JSON的双层嵌套逻辑:
struct Result: Codable { let dogs1: [Dog] let dogs2: [Dog] // 自定义解码初始化器 init(from decoder: Decoder) throws { // 根节点是数组,所以先创建一个无键容器(UnkeyedContainer) var unkeyedContainer = try decoder.unkeyedContainer() // 处理第一个数组元素:取出data -> children let firstItemContainer = try unkeyedContainer.nestedContainer(keyedBy: CodingKeys.self) let firstDataContainer = try firstItemContainer.nestedContainer(keyedBy: DataCodingKeys.self, forKey: .data) self.dogs1 = try firstDataContainer.decode([Dog].self, forKey: .children) // 处理第二个数组元素:同样取出data -> children let secondItemContainer = try unkeyedContainer.nestedContainer(keyedBy: CodingKeys.self) let secondDataContainer = try secondItemContainer.nestedContainer(keyedBy: DataCodingKeys.self, forKey: .data) self.dogs2 = try secondDataContainer.decode([Dog].self, forKey: .children) // 额外校验:如果数组元素超过2个,抛出错误(可选,根据你的需求调整) if !unkeyedContainer.isAtEnd { throw DecodingError.dataCorruptedError(in: unkeyedContainer, debugDescription: "JSON数组包含超过2个元素,不符合预期结构") } } // 用于解码外层对象的键 private enum CodingKeys: String, CodingKey { case data } // 用于解码data内部的键 private enum DataCodingKeys: String, CodingKey { case children } }
第三步:测试解码逻辑
你可以用下面的代码来验证解码是否正常工作:
// 你的原始JSON数据 let jsonString = """ [ { "data": { "children": [ {"name": "Ralph"}, {"name": "Woofer"} ] } }, { "data": { "children": [ {"name": "Spot"}, {"name": "Trevor"} ] } } ] """ // 尝试解码 do { let data = jsonString.data(using: .utf8)! let result = try JSONDecoder().decode(Result.self, from: data) print("Dogs1: \(result.dogs1.map(\.name))") // 输出:Dogs1: ["Ralph", "Woofer"] print("Dogs2: \(result.dogs2.map(\.name))") // 输出:Dogs2: ["Spot", "Trevor"] } catch { print("解码失败:\(error)") }
关键逻辑解释
- 无键容器(UnkeyedContainer):因为JSON的根节点是数组,所以我们用
unkeyedContainer()来遍历数组中的每个元素。 - 嵌套容器:对于数组里的每个对象,我们先取出
data对应的容器,再从data容器里取出children对应的[Dog]数组。 - 错误处理:加入了数组元素数量的校验,确保JSON结构符合预期,避免后续出现意外问题(你可以根据实际需求调整或移除这部分)。
内容的提问来源于stack exchange,提问作者Doug Smith
相关产品推荐
相关产品推荐

