如何解码包含多种Codable类型异构元素数组的JSON结构?
现有方案问题说明
你当前使用的泛型实现无法满足异构数组的解码需求:泛型参数Cell要求cells数组内所有元素必须是同一种类型,无法同时存储ChecklistCell、SegmentedCell等多种不同类型的实例。
无额外嵌套的实现方案
可以通过带关联值的枚举包装所有支持的Cell类型,手动实现Codable协议的编解码逻辑,不会在JSON中增加多余的嵌套层,完全匹配你给出的JSON结构。
完整实现代码如下:
// 原有Cell模型保持不变 struct ChecklistCell: Codable { let header: String } struct SegmentedCell: Codable { let title: String } // 枚举包装所有支持的Cell类型 enum CellType: Codable { case checklist(ChecklistCell) case segmented(SegmentedCell) init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() // 按顺序匹配Cell类型 if let checklistCell = try? container.decode(ChecklistCell.self) { self = .checklist(checklistCell) return } if let segmentedCell = try? container.decode(SegmentedCell.self) { self = .segmented(segmentedCell) return } // 匹配失败抛出错误 throw DecodingError.dataCorruptedError(in: container, debugDescription: "未识别的Cell类型") } func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() switch self { case .checklist(let cell): try container.encode(cell) case .segmented(let cell): try container.encode(cell) } } } // Submission不再需要泛型 struct Submission: Codable { let cells: [CellType] }
使用示例
let jsonData = """ { "cells": [ { "header": "dummy header" }, { "title": "dummy title" } ] } """.data(using: .utf8)! do { let submission = try JSONDecoder().decode(Submission.self, from: jsonData) for cell in submission.cells { switch cell { case .checklist(let cell): print("表头单元格内容:\(cell.header)") case .segmented(let cell): print("分段单元格标题:\(cell.title)") } } } catch { print("解码失败:\(error)") }
如果后续需要新增其他Cell类型,只需要给CellType枚举新增对应case,并在编解码逻辑中补充匹配分支即可。
内容的提问来源于stack exchange,提问作者EricE
相关产品推荐
相关产品推荐

