一个轻量级的 Swift JSON 解码器,没有任何依赖。它大致基于 Swift.org 的开源版本,用于替代 Apple 的 JSONSerialisation 框架。
目前用于
详细文档 可以在这里找到
此软件包中有两个解析器
TrailerJson
将一次性解析整个数据块,生成一个类似于 JSONSerialization 的字典。TypedJson
将快速扫描数据块并提供 Entry
类型的返回结果,这些结果具有类型化的访问方式(asInt
、asFloat
、asBool
、asString
等),并且仅在访问时才解析该数据。TrailerJson
解析器的性能几乎相当 *但是!* 结果都是原生 Swift 类型,因此使用这些结果不会产生桥接或复制成本,这是一个主要的性能优势。
TypedJson
解析器速度更快,如果您仅访问 JSON 数据的一个子集,则是理想的选择。它还可以在需要时并行化线程中的后续解析。
因为它在很大程度上牺牲了功能来换取只解码的性能,并且因为它返回原生 Swift 类型而无需将它们桥接到 ObjC 以实现兼容性,因此它在定义上比 Swift.org 版本更快。
👍 非常适合解析稳定的、已知的服务 API 响应,如 GraphQL,或在嵌入式设备上使用。自包含,没有设置开销。
👎 不擅长解析/验证可能损坏的 JSON,API 可能会突然包含意外的 schema 条目,或者当 Decodable
类型更好地为您服务时。
let url = URL(string: "http://date.jsontest.com")!
let data = try await URLSession.shared.data(from: url).0
// TrailerJson - parse in one go to [String: Sendable]
if let json = try data.asJsonObject(), // parse as dictionary
let timeField = json["time"],
let timeString = timeField as? String {
print("The time is", timeString)
}
// TypedJson - scan the data and only parse 'time' as a String
if let json = try data.asTypedJson(), // scan data
let timeField = try? json["time"],
let timeString = try? timeField.asString { // parse field
print("The time is", timeString)
}
TrailerJson 直接使用原始字节,因此它可以接受来自任何暴露原始字节缓冲区类型的数据,例如 NIO 的 ByteBuffer,而无需昂贵的类型转换或中间复制。
let byteBuffer: ByteBuffer = ...
// TrailerJson
let jsonArray = try byteBuffer.withVeryUnsafeBytes {
try TrailerJson.parse(bytes: $0) as? [Sendable]
}
let number = jsonArray[1] as? Int
print(number)
// TypedJson
let jsonArray = try byteBuffer.withVeryUnsafeBytes {
try TypedJson.parse(bytes: $0)
}
let number = try jsonArray[1].asInt
print(number)
// TypedJson - using bytesNoCopy, lazy parsing (max performance, but with caveats!)
let number = try byteBuffer.withVeryUnsafeBytes {
// jsonArray and any Entry from it must not be accessed outside the closure
let jsonArray = try TypedJson.parse(bytesNoCopy: $0)
// `secondEntry` reads from the original bytes, so it can't escape
let secondEntry = try jsonArray[1]
// but parsed values can escape
return try secondEntry.asInt
}
print(number)
如果您需要将 TypedJson 条目传递给需要非类型化字典的方法,您可以使用 parse
方法来急切地解析一个块 - 但请注意,对于大型数据集来说,这可能会很慢,因此最好用于非常特定的情况!
// TypedJson - eager parsing (slowest performance)
let numberArray = try byteBuffer.withVeryUnsafeBytes {
// numbers and any Entry from it must not be accessed outside the closure
let numbers = try TypedJson.parse(bytes: $0)
// but parsed value can escape - note that parsing the whole document would be
// very slow, so for cases like these the `TrailerJson` parser is 10x faster!
return try numbers.parsed as! [Int]
}
let number = numberArray[1]
print(number)
版权所有 (c) 2023-2024 Paul Tsochantaris. 根据 Apache License v2.0,带有运行时库例外,按照 其基于的开源材料。