OptionallyDecodable 将解码失败转换为可选值(optionals),而不是错误。
Swift 的 Codable
系统允许将对象简单地、声明式地编码为流行的序列化格式(如 JSON)并进行反序列化。
然而,在与许多 REST API 通信时,JSON 响应对象可能不像 Swift 希望的那样严格,此时 JSONDecoder
会放弃并抛出错误。 对于嵌套对象,此错误会传播到顶层对象,导致无法解码一个大型对象,仅仅因为嵌套在多层深处的一个元素意外地设置为 null
或一个迄今为止未知的枚举值。 即使您将该属性声明为可选,这也适用,因为只有 JSON null
或该值的缺失才会被解码为 nil
。
OptionallyDecodable 允许您注释那些不确定其确切组成的属性,原因可能是缺乏文档、错误的实现或处理 API 契约中意外的更改。
只需在您认为合适的“故障点”上注释一个属性。例如,在某些情况下,您可能只想在发送未知情况时使单个枚举值变为可选,而在某些情况下,您可能希望丢弃响应的更大部分,因为它不符合您的要求,因为一个过度积极的端点返回不完整的状态对象。
给定一个 JSON 响应,例如
{
"code": "OK",
"result": {
"text": "abc",
"number": 123
}
}
您可能希望将其解码为如下结构
enum Code: String, Decodable { case success = "OK", failure = "FAIL" }
struct Result: Decodable {
let text: String
let number: Int
}
struct Response: Decodable {
let code: Code
let result: Result
}
如果出于某种原因,API 响应突然遗漏了 text
或 number
字段,则 Result
对象和整个 Response
对象都将无法解码。 通过使用 @OptionallyDecodable
注释 result
属性并将其更改为可选的 var
,其解码失败将不会影响整个 Response
对象的解码。
同样,如果发现后端(可能是由于某个错误的微服务),有时会将 number
作为字符串而不是数字发送,您可以使其变为可选,并使用 @OptionallyDecodable
进行装饰。
枚举也是如此,声明枚举时,可能无法知道可能的返回代码的完整范围。 如果声明为 @OptionallyDecodable
,code
将静默地转换为 nil
(或 .none
),而不是抛出错误。
在 Xcode 中,选择 File → Swift Packages → Add Package Dependency 并粘贴到此 repo 的链接。
只需将 OptionallyDecodable.swift
复制到您的项目中。