Swift如何将扁平JSON解码为带嵌套结构的结构体对象
扁平JSON解码为嵌套结构体的最简实现方案
直接使用Swift原生Codable的自定义初始化方法实现即可,零依赖、逻辑直白易维护,是落地成本最低的方案。
实现步骤
- 给外层
Day结构体定义CodingKeys,列出JSON根层级存在的所有字段,不需要从JSON读取的id字段不用放入 - 重写
init(from decoder:)方法,从根解码容器中分别读取外层需要的date字段,以及嵌套DayData需要的三个统计字段,组装成目标嵌套结构即可
完整代码
给目标结构体加入自定义解码逻辑即可,不需要改动你定义的嵌套结构:
struct Day: Codable, Identifiable { var id = UUID() var date : String var dayData: [DayData] struct DayData: Codable { var personel: Int var plane: Int var drone: Int } // 对应JSON根层级的字段键 enum CodingKeys: String, CodingKey { case date, personel, plane, drone } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) // 解析外层字段 date = try container.decode(String.self, forKey: .date) // 从同一根容器解析嵌套结构体需要的字段,组装后放入数组 let singleDayData = DayData( personel: try container.decode(Int.self, forKey: .personel), plane: try container.decode(Int.self, forKey: .plane), drone: try container.decode(Int.self, forKey: .drone) ) dayData = [singleDayData] } }
调用方式
和普通Codable解码完全一致,注意先把你提供的JSON示例末尾多余的逗号删掉(非法JSON格式会导致解码失败):
// 合法JSON字符串 let jsonStr = """ { "date": "2022-02-24T00:00:00.000Z", "personel": 800, "plane": 7, "drone": 6 } """ guard let jsonData = jsonStr.data(using: .utf8) else { return } do { let dayResult = try JSONDecoder().decode(Day.self, from: jsonData) // 解码完成即可直接使用嵌套结构 print(dayResult.date) print(dayResult.dayData.first?.drone ?? 0) } catch { print("解码错误:\(error)") }
方案优势
- 无任何第三方依赖,基于Swift原生能力实现,不存在版本兼容问题
- 逻辑透明,后续新增/修改字段只需要调整CodingKeys和初始化方法里的解析逻辑,维护成本极低
- 解码性能和系统默认Codable解码完全一致,不需要先转字典做二次组装,没有额外性能损耗
内容的提问来源于stack exchange,提问作者Roman R
相关产品推荐
相关产品推荐

