Swift中如何获取名称含连字符的JSON属性?
Swift JSONDecoder处理含连字符的JSON属性名解决办法
方法一:自定义CodingKeys枚举(推荐)
通过实现Codable协议的CodingKeys枚举,直接映射JSON属性名和合法的Swift变量名,这是最直观且易维护的方案。
示例代码:
struct NutritionInfo: Codable { // 用Swift合法命名定义变量 let saturatedFat100g: Double // 定义CodingKeys枚举,关联JSON中的属性名 enum CodingKeys: String, CodingKey { case saturatedFat100g = "saturated-fat_100g" } } // 解码操作示例 let jsonString = """ { "saturated-fat_100g": 5.2 } """ guard let jsonData = jsonString.data(using: .utf8) else { fatalError("JSON字符串转数据失败") } do { let nutrition = try JSONDecoder().decode(NutritionInfo.self, from: jsonData) print(nutrition.saturatedFat100g) // 输出: 5.2 } catch { print("解码错误: \(error.localizedDescription)") }
方法二:自定义keyDecodingStrategy(批量处理场景)
如果API返回的JSON中有大量含连字符、下划线的属性名,可以通过自定义JSONDecoder的keyDecodingStrategy来批量转换命名规则,无需逐个定义CodingKeys。
示例代码:
struct NutritionInfo: Codable { let saturatedFat100g: Double // 其他同规则属性可直接按驼峰命名定义 } let decoder = JSONDecoder() decoder.keyDecodingStrategy = .custom { codingPath in let originalKey = codingPath.last!.stringValue // 先替换连字符为空,再将下划线分隔的命名转为驼峰式 let hyphenRemoved = originalKey.replacingOccurrences(of: "-", with: "") let components = hyphenRemoved.components(separatedBy: "_") guard components.count > 1 else { return codingPath.last! } let camelCaseKey = components[0] + components.dropFirst() .map { $0.prefix(1).uppercased() + $0.dropFirst() } .joined() return CodingKey(stringValue: camelCaseKey)! } // 解码操作同方法一 let jsonString = """ { "saturated-fat_100g": 5.2 } """ guard let jsonData = jsonString.data(using: .utf8) else { fatalError("JSON字符串转数据失败") } do { let nutrition = try decoder.decode(NutritionInfo.self, from: jsonData) print(nutrition.saturatedFat100g) // 输出: 5.2 } catch { print("解码错误: \(error.localizedDescription)") }
总结
- 单个属性名不匹配时,优先用CodingKeys枚举,逻辑清晰且便于后续维护。
- 大量属性存在相同命名规则时,用自定义keyDecodingStrategy可以减少重复代码。
内容的提问来源于stack exchange,提问作者mirco03
相关产品推荐
相关产品推荐

