SwiftUI配置convertFromSnakeCase解码策略后报keyNotFound找不到is_paid键
根因定位
核心问题为 键解码策略与模型命名规则不匹配。
设置keyDecodingStrategy = .convertFromSnakeCase后,解码器会将JSON原始的蛇形键名自动转换为驼峰格式,再与模型的CodingKeys(即模型属性名)做匹配。
对应实际匹配逻辑:
- 定义的
Invoices模型自动生成的CodingKeys为:id、is_paid、total、invoice_id - 开启
.convertFromSnakeCase后,JSON原始键的转换结果为:id(无下划线,转换后仍为id)→ 匹配模型的id,解码正常total(无下划线,转换后仍为total)→ 匹配模型的total,解码正常is_paid→ 转换为isPaid→ 模型CodingKeys中无此键,触发keyNotFound报错invoice_id→ 转换为invoiceId→ 模型CodingKeys中无此键,触发keyNotFound报错
不设置自定义键解码策略时,解码器直接使用JSON原始键名与模型属性名匹配,接口返回的蛇形键与模型的蛇形属性完全一致,因此可正常完成解码。
此前使用GetInvoices包装模型失败,是因为接口直接返回顶层发票数组,并非包含invoices字段的包裹结构,与解码策略无关,属于模型结构与接口返回格式不匹配。
解决方案
任选以下一种方案即可:
方案1:移除蛇形转驼峰的解码策略
直接删除设置keyDecodingStrategy的代码,使用默认解码策略,完全适配当前接口返回格式与模型命名。
对应修改后的解码器代码:
let decoder = JSONDecoder() // 删除 decoder.keyDecodingStrategy = .convertFromSnakeCase 这行代码
方案2:保留解码策略,调整模型命名为驼峰格式
如果需要保留统一的蛇形转驼峰解码规则,将模型属性改为驼峰命名,匹配转换后的JSON键:
struct Invoices: Decodable, Hashable, Identifiable { let id: Int let isPaid: Int // 对应JSON的is_paid转换后的isPaid let total: Double let invoiceId: String // 对应JSON的invoice_id转换后的invoiceId }
如果需要保留原有自定义属性名,可手动实现CodingKeys做映射:
struct Invoices: Decodable, Hashable, Identifiable { let id: Int let isPaid: Int let total: Double let invoiceID: String enum CodingKeys: String, CodingKey { case id case isPaid case total case invoiceID = "invoiceId" } }
内容的提问来源于stack exchange,提问作者OminousMusic
相关产品推荐
相关产品推荐

