优雅、类型安全的 Swift JSON 解析
如果你是一位聪明的程序员,那么你可能会尽可能地使用 Codable
类型。然而,有时你需要解析一些你无法控制结构的 JSON 数据。以前,这是一个痛苦的操作。
let object = try (JSONSerialization.jsonObject(with: data) as! [String: Any])
guard let foo = object["foo"] as? Int, let bar = object["bar"] as? String, let array = object["array"] as? [Any] else {
return
}
guard let number = array[0] as? Double, let word = array[1] as? String, let dictionary = array[3] as? [String: Int] else {
return
}
guard let hello = dictionary["hello"] else {
return
}
使用 JSONParser,这个过程变得优雅且毫不费力。
let parser = data.dictionaryParser // `data` is an instance of `Data` from `Foundation`
let foo = parser["foo", as: Int.self]
let bar = parser["bar", as: String.self]
let number = parser[arrayAt: "array"]?[0, as: Double.self]
let word = parser[arrayAt: "array"]?[1, as: String.self]
let hello = parser[arrayAt: "array"]?[dictionaryAt: 2]?["hello", as: Int.self]
你还可以遍历异构 JSON 数组和字典。
try data.arrayParser.iterate { (proxy) in
if let value = proxy.get(as: Int.self) {
print(value * 2)
} else if let value = proxy.get(as: Bool.self) {
print(!value)
}
}
JSONParser 可以与其他提供者一起工作,不仅仅是来自 Foundation
的 Data
。只需让你的自定义类或结构体遵循 JSONProvider
协议。它只有一个强制性的接口成员。
// This `Set` extension is already provided in the JSONParser package; use it as a guide for writing your own extensions for other types
extension Set: JSONProvider {
public var parser: ArrayJSONParser? {
get {
return Array(self).parser
}
}
}
便捷的函数和下标访问器会自动免费提供,无需手动实现。
let array = [
0,
1,
[
"2": true
]
] as [AnyHashable]
let set = Set(array)
try set.iterate { (proxy) in
print(proxy.get(as: Int.self) ?? proxy.get(as: [String: Bool].self)!)
}
JSONParser 构建于 Swift 强大的泛型类型系统之上,以提供一个简单、直观的 API 用于与 JSON 数据交互。它没有外部依赖,并且完全依赖于 Foundation
API,因此,除了各种 Apple 平台外,它还可以在 Linux 和 Windows 上运行。