Swift解析JSON文件报数据无效 如何构建匹配的Codable数据模型
Swift JSONDecoder 解码错误解决方案
错误核心原因
你的模型结构与数据类型均和实际JSON结构不匹配,是导致抛出The given data was not valid JSON错误的直接原因:
- Country、Ambulance等字段不是单层String类型,是包含
All属性的嵌套对象,模型直接声明为String会出现层级不匹配 - 嵌套对象中
All对应的是字符串数组[String],即便直接声明为String类型也会出现类型不匹配
两种修复方案
方案1:新增嵌套模型匹配JSON层级
适合需要保留完整JSON结构的场景,定义通用嵌套层模型即可:
// 通用嵌套层模型,匹配包含All属性的对象结构 struct NestedCategory: Codable { let all: [String] // 若JSON中键为大写All,需通过CodingKeys映射 enum CodingKeys: String, CodingKey { case all = "All" } } // 主解析模型 struct EmergencyNumberModel: Codable { let country: NestedCategory let ambulance: NestedCategory // 其余同结构字段依次声明即可 enum CodingKeys: String, CodingKey { case country = "Country" case ambulance = "Ambulance" } }
方案2:自定义解码逻辑,直接提取内层值
不需要额外定义嵌套模型,直接把All对应的数组赋值给主模型属性:
struct EmergencyNumberModel: Codable { let country: [String] let ambulance: [String] enum CodingKeys: String, CodingKey { case country = "Country" case ambulance = "Ambulance" // 嵌套层All键的编码规则 enum InnerCodingKeys: String, CodingKey { case all = "All" } } init(from decoder: Decoder) throws { let rootContainer = try decoder.container(keyedBy: CodingKeys.self) // 手动提取Country嵌套层的All数组 let countryContainer = try rootContainer.nestedContainer(keyedBy: CodingKeys.InnerCodingKeys.self, forKey: .country) self.country = try countryContainer.decode([String].self, forKey: .all) // 手动提取Ambulance嵌套层的All数组 let ambulanceContainer = try rootContainer.nestedContainer(keyedBy: CodingKeys.InnerCodingKeys.self, forKey: .ambulance) self.ambulance = try ambulanceContainer.decode([String].self, forKey: .all) } }
额外排查项
如果修改模型后仍抛出相同错误,可先读取本地JSON文件的Data并转成UTF8字符串打印,确认JSON本身不存在格式错误(如缺失括号、尾部多余逗号等问题)。
内容的提问来源于stack exchange,提问作者René Tarot
相关产品推荐
相关产品推荐

