Swift JSON Decoder解析混合结构数组问题求助
问题描述
给定如下不规则JSON结构:
[ { "texts": [ { "value": "value 1" } ], "commentType": "someComment" }, { "texts": [ { "value": "value 2" } ], "commentType": "someComment2" }, { "texts": [ { "evidences": [ { "evidenceCode": "code 1" }, { "evidenceCode": "code 2" }, { "evidenceCode": "code 3" }, { "evidenceCode": "code 4" } ], "value": "value 3" } ], "commentType": "someComment3" } ]
现有解析代码可处理前两个texts字段和commentType,代码如下:
enum CodingKeys: String, CodingKey { case texts case commentType } do { let container = try decoder.container(keyedBy: CodingKeys.self) let name = try container.decode(String.self, forKey: .commentType) if let texts = try container.decodeIfPresent([[String: String]].self, forKey: .texts) { for text in texts { if let value = text["value"] { // add to model object } } } } catch { print(error) }
但解析第三个texts块时触发错误:
"Expected to decode String but found an array instead."
原因是第三个texts内的元素并非纯[String:String]结构,而是包含evidences数组与value字段的混合结构,需调整解析逻辑提取value 3。
解决方案
不要直接用[[String: String]]解码texts,自定义TextItem类型处理混合结构,通过自定义init(from decoder: Decoder)方法兼容两种情况:
// 定义对应JSON结构的模型 struct Comment: Decodable { let commentType: String let texts: [TextItem] } struct TextItem: Decodable { let value: String let evidences: [Evidence]? // 可选字段,对应第三个item的evidences struct Evidence: Decodable { let evidenceCode: String } enum CodingKeys: String, CodingKey { case value, evidences } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) // 强制解析value字段,所有textItem均包含该字段 self.value = try container.decode(String.self, forKey: .value) // 尝试解析evidences,无该字段则设为nil self.evidences = try container.decodeIfPresent([Evidence].self, forKey: .evidences) } } // 解析调用示例 do { let comments = try JSONDecoder().decode([Comment].self, from: yourJsonData) for comment in comments { print("CommentType: \(comment.commentType)") for textItem in comment.texts { print("Value: \(textItem.value)") // 若存在evidences可额外处理 if let evidences = textItem.evidences { print("Evidences: \(evidences.map(\.evidenceCode))") } } } } catch { print(error) }
逻辑说明
- 外层
Comment模型对应JSON的顶层结构,包含commentType和texts数组 TextItem模型包含必填的value和可选的evidences,自定义解码方法确保无论是否存在evidences数组,都能正确提取value- 该方式同时兼容前两个无
evidences的texts元素,以及第三个带evidences的元素,避免类型不匹配错误
内容的提问来源于stack exchange,提问作者koen
相关产品推荐
相关产品推荐

