Swift枚举解码JSON未知值:如何实现unknown案例?
解决枚举解码未知值崩溃的问题
你遇到的这个场景太常见了——默认的RawRepresentable枚举解码逻辑,会在遇到未定义的原始值时直接抛出错误,导致整个解码流程崩溃。要实现unknown案例来捕获所有未匹配的情况,我们只需要自定义枚举的解码初始化方法就行:
修改后的AnimalType枚举代码
extension AnimalStore.Store.Animal { enum AnimalType: String, Decodable { case dog = "dog" case cat = "cat" case unknown // 自定义解码逻辑 init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() let rawValue = try container.decode(String.self) // 尝试匹配已定义的case,匹配失败就返回unknown self = AnimalType(rawValue: rawValue) ?? .unknown } } }
逻辑说明
- 先新增
case unknown,不需要指定rawValue——毕竟我们要捕获所有dog/cat之外的字符串,留空就好; - 重写
init(from decoder: Decoder)方法:- 先获取解码的单值容器,读出原始字符串;
- 用枚举的默认构造器尝试转换,转换失败时直接返回
.unknown。
这样修改后,不管遇到"bird"、"fish"这类未知值,解码都会顺利完成,type会被设置为.unknown,再也不会崩溃啦。
如果后续需要排查问题,想把未知的原始值保存下来,还可以改成关联值形式的枚举:
extension AnimalStore.Store.Animal { enum AnimalType: Decodable { case dog case cat case unknown(String) init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() let rawValue = try container.decode(String.self) switch rawValue { case "dog": self = .dog case "cat": self = .cat default: self = .unknown(rawValue) } } // 如果需要支持编码,可额外实现RawRepresentable var rawValue: String { switch self { case .dog: return "dog" case .cat: return "cat" case .unknown(let value): return value } } } }
这种方式能把未知的原始值存储起来,方便后续做日志记录或者特殊业务处理。
内容的提问来源于stack exchange,提问作者emrepun
相关产品推荐
相关产品推荐

