Swift自定义Decoder如何处理嵌套Container不存在时的nil值问题
解决方法
你当前代码崩溃的核心原因是nestedContainer(keyedBy:forKey:)方法在对应key不存在时会直接抛出解码错误,只需将这一步改为可选判断逻辑即可兼容name字段完全缺失的场景,修改后的完整代码如下:
struct UserModel: Decodable { var gender: String var title: String? var first: String? var last: String? // 顶层编码键 enum CodingKeys: String, CodingKey { case name, gender } enum NameKeys: CodingKey { case title, first, last } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) gender = try container.decode(String.self, forKey: .gender) // 新增判断:只有name字段存在时才解析内部字段 if container.contains(.name) { let name = try container.nestedContainer(keyedBy: NameKeys.self, forKey: .name) title = try name.decodeIfPresent(String.self, forKey: .title) first = try name.decodeIfPresent(String.self, forKey: .first) last = try name.decodeIfPresent(String.self, forKey: .last) } // 如果name字段不存在,三个可选属性默认保持nil即可 } }
可选替代写法
如果你不想用contains判断,也可以用try?捕获获取嵌套容器的错误,效果完全一致:
init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) gender = try container.decode(String.self, forKey: .gender) // 获取嵌套容器失败时直接跳过解析 if let name = try? container.nestedContainer(keyedBy: NameKeys.self, forKey: .name) { title = try name.decodeIfPresent(String.self, forKey: .title) first = try name.decodeIfPresent(String.self, forKey: .first) last = try name.decodeIfPresent(String.self, forKey: .last) } }
两种写法都可以实现:就算顶层name字段完全缺失,解码也能正常完成,title、first、last三个属性会自动为nil,不会抛出崩溃错误。
内容的提问来源于stack exchange,提问作者Simon McNeil
相关产品推荐
相关产品推荐

