Swift如何解析同一数组中键大小写不同的相似JSON
Swift 兼容大小写不同键名的同结构JSON解析方案
方案一:自定义全局键解码策略(推荐,适配全量场景)
这个方案通过将所有输入的JSON键统一转为小写(和你定义的CodingKey保持一致)实现自动匹配,不需要修改每个数据模型的解码逻辑。
首先实现辅助工具类和自定义策略:
// 通用CodingKey辅助类型 struct AnyCodingKey: CodingKey { let stringValue: String let intValue: Int? init?(stringValue: String) { self.stringValue = stringValue self.intValue = nil } init?(intValue: Int) { self.intValue = intValue self.stringValue = "\(intValue)" } } extension JSONDecoder.KeyDecodingStrategy { // 大小写不敏感解码策略:自动将输入键转为小写后匹配 static var caseInsensitive: Self { .custom { codingPath in let originKey = codingPath.last!.stringValue.lowercased() return AnyCodingKey(stringValue: originKey)! } } }
然后定义你的数据模型,CodingKey统一用小写格式即可:
struct LocationModel: Codable { let gpsX: Double let gpsY: Double // 其他属性 enum CodingKeys: String, CodingKey { case gpsX = "gps_x" case gpsY = "gps_y" // 其他小写格式键 } }
使用时仅需给解码器设置对应策略:
let decoder = JSONDecoder() decoder.keyDecodingStrategy = .caseInsensitive // 全小写JSON和全大写JSON都可以用同一个方法解析 let model = try decoder.decode(LocationModel.self, from: jsonData)
方案二:手动实现解码初始化方法(灵活适配特殊场景)
如果仅需要针对单个模型做大小写兼容,不需要全局修改解码策略,可以手动实现init(from decoder: Decoder)方法,分别匹配大小写两种键:
struct LocationModel: Codable { let gpsX: Double let gpsY: Double init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: AnyCodingKey.self) // 优先匹配小写键,匹配失败再尝试大写键 gpsX = try container.decodeIfPresent(Double.self, forKey: AnyCodingKey(stringValue: "gps_x")!) ?? container.decode(Double.self, forKey: AnyCodingKey(stringValue: "GPS_X")!) gpsY = try container.decodeIfPresent(Double.self, forKey: AnyCodingKey(stringValue: "gps_y")!) ?? container.decode(Double.self, forKey: AnyCodingKey(stringValue: "GPS_Y")!) } }
该方案不需要修改解码器的全局配置,也可以适配部分键命名规则特殊的场景。
内容的提问来源于stack exchange,提问作者Александр Зарудний
相关产品推荐
相关产品推荐

