Swift Codable解析问题:JSON中fontSize同时存在Int与String类型
解决JSON中fontSize同时存在Int和String类型的Codable解析问题
直接自定义Element结构体的解码逻辑,在init(from decoder:)方法里兼容两种类型的解析:
import Foundation struct Element: Codable, Identifiable { let id: UUID // 按实际id类型调整,这里假设是UUID let fontSize: Int? enum CodingKeys: String, CodingKey { case id, fontSize } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) // 解析id字段 id = try container.decode(UUID.self, forKey: .id) // 处理fontSize的双类型兼容 do { // 优先尝试解析为Int类型 fontSize = try container.decode(Int?.self, forKey: .fontSize) } catch DecodingError.typeMismatch { // 类型不匹配时,尝试解析为String再转Int if let fontSizeStr = try? container.decode(String?.self, forKey: .fontSize), let fontSizeInt = fontSizeStr.flatMap(Int.init) { fontSize = fontSizeInt } else { // 两种类型都解析失败时设为nil,避免整个模型解析崩溃 fontSize = nil } } } }
如果有多个字段存在类似的类型不统一问题,可以封装一个通用的兼容类型来复用逻辑:
struct StringOrInt: Codable { let value: Int? init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() do { value = try container.decode(Int?.self) } catch DecodingError.typeMismatch { if let str = try? container.decode(String?.self) { value = str.flatMap(Int.init) } else { value = nil } } } } // 在Element中使用该类型 struct Element: Codable, Identifiable { let id: UUID let fontSize: StringOrInt // 可选:添加计算属性直接获取Int?值 var fontSizeInt: Int? { fontSize.value } }
核心逻辑说明
- 第一种方案直接在目标结构体内部处理,适合仅单个字段需要兼容的场景,逻辑直观。
- 第二种方案的通用类型可重复利用,多字段兼容时更高效。
- 两种方案都做了容错处理:如果字段既不是Int,也不是可转换为Int的String,最终会将
fontSize设为nil,避免整个模型解析失败。
内容的提问来源于stack exchange,提问作者Kancey
相关产品推荐
相关产品推荐

