为 Foundation.JSONDecoder 添加嵌套键路径支持
在撰写本文时,我发现大多数流行的框架(主要是网络封装器)在处理键路径时做了一些糟糕的事情。
因此,假设我们有一个 Decodable
(Codable
) 对象,但在 API 响应中,我们是在某个自定义路径下获取它。大多数解决方案已经有通过键路径提取对象的接口,并且还添加了 Codable
支持。但问题是,在我看到的所有案例中,几乎所有实现都是这样的:
JSONSerialization
从 Data
中提取 [String: Any]
Data
JSONDecoder
解析对象显而易见,数据的来回转换是对资源的额外浪费。此外,对于大量数据,这是非常不可取的。
此软件包消除了前 3 个步骤。
假设你有一个 Item
模型
struct Item: Codable {
...
}
我们有以下 JSON
{
"foo" : <actual object>
}
要解析它,你需要这样写
let jsonData: Data = ...
let item = try decoder.decode(Item.self, from: jsonData, keyPath: "foo")
也支持嵌套键路径
let item = try decoder.decode(Item.self, from: jsonData, keyPath: "foo.bar")
键路径分隔符可以配置
let item = try decoder.decode(Item.self, from: jsonData, keyPath: "foo/bar", keyPathSeparator: "/")
软件包向 JSONDecoder
添加了新方法
func decode<T>(_ type: T.Type,
from data: Data,
keyPath: String,
keyPathSeparator separator: String = ".") throws -> T where T : Decodable
在这个调用中,keypath
存储在 JSONDecoder.userInfo
中,然后使用私有类 KeyPathWrapper<T>
作为类型参数调用标准的 decode
方法。在 KeyPathWrapper
构造函数中,从 userInfo
中获取键路径数据,并使用这些值遍历解码器。之后,原始类型被解码。
将 .Package(url: "https://github.com/0111b/JSONDecoder-Keypath.git")
行添加到你的 Package.swift
pod 'JSONDecoder-Keypath'
这基本上是自定义对象编码的幼稚实现,只花了我几个小时。但它表明我们必须思考如何使用提供的 API,并且不要懒于查看底层原理