iOS 13中JSONDecoder.convertFromSnakeCase失效?单元测试解码异常排查
解决iOS 13/Xcode 11下JSONDecoder convertFromSnakeCase解码失败的问题
我之前也碰到过类似的版本升级后解码异常的情况,结合你的代码、报错信息和场景,咱们来一步步拆解解决:
问题根源分析
你的DiscogsInfo结构体中,documentationUrl属性对应JSON里的documentation_url,按道理convertFromSnakeCase策略应该自动完成蛇形命名到驼峰命名的转换,但报错却显示找不到documentationUrl键,说明解码器并没有正确应用这个策略。
大概率是两个原因之一:
- 解码器实例未正确复用:你可能在解码时临时创建了新的
JSONDecoder,而没有使用已经配置好keyDecodingStrategy的那个实例——默认情况下新解码器的策略是.useDefaultKeys,自然无法匹配蛇形键。 - iOS 13对策略的处理细节变化:虽然官方文档没明确标注,但iOS13对部分特殊命名的转换逻辑有更严格的要求,比如小写开头的蛇形键对应大写开头的驼峰属性时,可能出现转换失效。
具体解决方案
方案1:确保解码器策略被正确应用
先检查你的解码代码,务必复用同一个配置好策略的解码器实例:
// 全局/局部复用这个配置好的解码器 let jsonDecoder = JSONDecoder() jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase // 解码时直接使用这个实例 do { let discogsInfo = try jsonDecoder.decode(DiscogsInfo.self, from: jsonData) // 处理解析结果 } catch { print("解码失败:\(error)") }
别在每次解码时都写let decoder = JSONDecoder(),这样会重置所有配置。
方案2:手动指定CodingKeys(最稳妥)
如果依赖系统策略不稳定,手动添加CodingKeys是彻底规避版本兼容性问题的方式,解码逻辑完全可控:
public struct DiscogsInfo: Codable { public var apiVersion: String? public var documentationUrl: URL public var hello: String public var statistics: Stats // 手动映射JSON键和属性名 enum CodingKeys: String, CodingKey { case apiVersion = "api_version" case documentationUrl = "documentation_url" case hello case statistics } public struct Stats: Codable { public var labels: Int public var artists: Int public var releases: Int enum CodingKeys: String, CodingKey { case labels, artists, releases } } }
这种方式不管系统策略怎么变,都能保证键名映射的准确性。
方案3:验证iOS 13策略的实际行为
可以写个极简测试用例,确认convertFromSnakeCase在iOS13下的表现:
struct TestModel: Codable { let documentationUrl: String } let testJson = #"{"documentation_url": "https://example.com"}"#.data(using: .utf8)! let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase do { let model = try decoder.decode(TestModel.self, from: testJson) print("解析成功:\(model.documentationUrl)") } catch { print("解析失败:\(error)") }
如果这个测试也失败,说明确实是iOS13的策略bug,此时方案2就是最优解。
总结
先排查解码器实例的复用问题,确认策略配置无误后如果仍报错,手动添加CodingKeys是最可靠的解决方式,能彻底避免系统版本带来的行为差异。
内容的提问来源于stack exchange,提问作者NRitH
相关产品推荐
相关产品推荐

