Swift中解码[String:Int]字典时蛇形键转驼峰策略失效问题
Swift Codable:解决stats/increase字段蛇形键转驼峰无效的问题
问题场景
原始JSON数据如下:
{"message": "The data were fetched successfully.","data": {"date": "2022-07-22","day": 149,"resource": "https://www.someWebsite.com","stats": {"personnel_units": 39000,"tanks": 1704,"armoured_fighting_vehicles": 3920,"artillery_systems": 863,"mlrs": 251,"aa_warfare_systems": 113,"planes": 221,"helicopters": 188,"vehicles_fuel_tanks": 2803,"warships_cutters": 15,"cruise_missiles": 167,"uav_systems": 713,"special_military_equip": 72,"atgm_srbm_systems": 4},"increase": {"personnel_units": 150,"tanks": 0,"armoured_fighting_vehicles": 8,"artillery_systems": 4,"mlrs": 0,"aa_warfare_systems": 0,"planes": 0,"helicopters": 0,"vehicles_fuel_tanks": 22,"warships_cutters": 0,"cruise_missiles": 0,"uav_systems": 3,"special_military_equip": 0,"atgm_srbm_systems": 0}}}
通过quicktype生成的结构体如下:
struct DataModel: Codable { var message: String var data: ObjectsModel } struct ObjectsModel: Codable { var date: String var day: Int var resource: String var stats, increase: [String: Int] }
当前遇到的问题:设置decoder.keyDecodingStrategy = .convertFromSnakeCase后,stats和increase内部的蛇形键(比如personnel_units)无法转换为驼峰格式,也没办法给这些内部键设置CodingKeys做映射。
问题原因
因为stats和increase被定义成了[String: Int]字典类型,而keyDecodingStrategy的转换逻辑只会作用于结构体的属性名,不会处理字典内部的键值对,所以蛇形键转驼峰的策略对字典里的键无效,也没法用CodingKeys来映射这些字典键。
解决方案
把stats和increase对应的字典转换成具体的Codable结构体,这样就能利用Swift的自动键解码策略,或者手动设置CodingKeys来实现蛇形键到驼峰属性的映射。
步骤1:定义统一的统计数据结构体
因为stats和increase的键结构完全一致,可以复用同一个结构体:
struct MilitaryStats: Codable { let personnelUnits: Int let tanks: Int let armouredFightingVehicles: Int let artillerySystems: Int let mlrs: Int let aaWarfareSystems: Int let planes: Int let helicopters: Int let vehiclesFuelTanks: Int let warshipsCutters: Int let cruiseMissiles: Int let uavSystems: Int let specialMilitaryEquip: Int let atgmSrbmSystems: Int }
步骤2:修改ObjectsModel的属性类型
把原来的[String: Int]替换成上面定义的MilitaryStats:
struct ObjectsModel: Codable { let date: String let day: Int let resource: String let stats: MilitaryStats let increase: MilitaryStats } struct DataModel: Codable { let message: String let data: ObjectsModel }
步骤3:解码时设置键转换策略
现在设置convertFromSnakeCase就能自动把JSON里的蛇形键转换成结构体的驼峰属性名:
let jsonData = // 你的JSON数据Data对象 let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase do { let model = try decoder.decode(DataModel.self, from: jsonData) // 访问驼峰格式的属性,比如model.data.stats.personnelUnits print(model.data.stats.personnelUnits) } catch { print("解码失败:\(error)") }
可选:手动设置CodingKeys(如果不想用自动转换)
如果需要手动映射键,也可以给MilitaryStats添加CodingKeys:
struct MilitaryStats: Codable { let personnelUnits: Int let tanks: Int // ... 其他属性 enum CodingKeys: String, CodingKey { case personnelUnits = "personnel_units" case tanks case armouredFightingVehicles = "armoured_fighting_vehicles" // ... 其他键的映射 } }
这种方式不需要设置keyDecodingStrategy,直接通过CodingKeys完成蛇形键到驼峰属性的映射。
内容的提问来源于stack exchange,提问作者Ozzzie
相关产品推荐
相关产品推荐

