轻松加载 JSON 对象并将它们解码为结构体或类。 json(atKeyPath:)
函数会从常量或变量定义中推断类型以进行解码,这意味着无需类型转换。在解码 JSON 时,字符串键和键路径(以点 .
分隔的键)均受支持。
JSONUtilities.xcodeproj
中的 Example.playground
以获取可运行的示例CocoaPods
将行 pod 'JSONUtilities'
添加到您的 Podfile
。
Carthage
将行 github "lucianomarisi/JSONUtilities"
添加到您的 Cartfile
。
手动
将 Sources
文件夹中的文件添加到您的 Xcode 项目中。
Swift Package Manager
将行 .Package(url: "https://github.com/lucianomarisi/JSONUtilities", majorVersion: 3)
添加到您的 Package.swift
。
Int
Double
Float
String
Bool
[String: AnyObject]
RawRepresentable
枚举[Int]
[Double]
[Float]
[String]
[Bool]
[[String: AnyObject]]
[RawRepresentable]
例如,如果 MyClass
和 MyStruct
遵循 JSONObjectConvertible
协议
MyClass
MyClass
]MyStruct
MyStruct
][JSONKey: JSONRawType]
[JSONKey: JSONObjectConvertible]
[JSONKey: JSONPrimitiveConvertible]
[JSONKey: RawRepresentable]
String 已经遵循 JSONKey。通过使枚举键遵循 JSONKey 也很容易创建枚举键,这需要一个 var key: String { get }
和一个 init?(rawValue: String)
,RawRepresentable 已经遵循了,例如
enum MyEnum: String, JSONKey {
case one
case two
var key: String {
return rawValue
}
}
当解码数组或字典时,可以传递 invalidItemBehaviour
参数,该参数控制在解码子项时发生错误时会发生什么
.remove
这将简单地从数组或字典中删除该项。这是默认行为.fail
如果任何子项遇到错误,则整个数组或字典解码将失败。对于可选属性,这意味着数组或字典将返回 nil,对于非可选属性,它将抛出错误.value(T)
提供替代值.custom((DecodingError) -> InvalidItemBehaviour)
允许您根据特定的 DecodingError 指定行为每个 json(atKeyPath:) 函数都接受一个 KeyPath。这是一个具有 2 种情况的枚举
key(String)
- 这执行单个键查找keyPath([String])
- 这执行嵌套键查找KeyPath 可以使用字符串字面量初始化。这样做时,如果存在任何 .
,它将被视为键路径而不是简单键。
当提供键路径时,int 允许按索引查找数组中的值。例如:"myArray.1"
字符串字面量将查找键 myArray
,然后查找该值(如果该值是数组)的第 2 项(索引从 0 开始)
let filename = "myjsonfile"
let dictionary: [String: AnyObject] = try JSONDictionary.from(filename: filename)
let data: Data = ...
let dictionary: [String: AnyObject] = try JSONDictionary.from(jsonData: data)
考虑一个表示人的 JSON 对象
{
"name" : "John Doe",
"age" : 24,
"weight" : 72.4
}
let jsonDictionary = try JSONDictionary.from(filename: "person.json")
let name: String = try jsonDictionary.json(atKeyPath: "name")
let age: Int = try jsonDictionary.json(atKeyPath: "age")
let weight: Int = try jsonDictionary.json(atKeyPath: "weight")
let profession: String? = jsonDictionary.json(atKeyPath: "profession") // Optional decoding
struct Person { //OR class Person {
let name: String
let age: Int
let weight: Double
let profession: String?
init(jsonDictionary: JSONDictionary) throws {
name = try jsonDictionary.json(atKeyPath: "name")
age = try jsonDictionary.json(atKeyPath: "age")
weight = try jsonDictionary.json(atKeyPath: "weight")
profession = jsonDictionary.json(atKeyPath: "profession")
}
}
考虑一个公司 JSON 对象
{
"name" : "Working name LTD.",
"employees": [
{
"name": "John Doe",
"age": 24,
"weight": 72.4
},
{
"name": "Jane Doe",
"age": 22,
"weight": 70.1
}
]
}
Company
结构体可以通过使 Person
结构体/类遵循 JSONObjectConvertible
协议来解码 Person
结构体/类的数组
struct Company {
let name: String
let employees: [Person]
init(jsonDictionary: JSONDictionary) throws {
name = try jsonDictionary.json(atKeyPath: "name")
employees = try jsonDictionary.json(atKeyPath: "employees")
}
}
任何类型都可以扩展 JSONPrimitiveConvertible
协议以允许解码。例如扩展 URL
:请注意,此扩展是开箱即用的
extension URL: JSONPrimitiveConvertible {
public typealias JSONType = String
public static func from(jsonValue: String) -> Self? {
return self.init(string: jsonValue)
}
}
let urlDictionary = ["url": "www.google.com"]
let url: URL = try! urlDictionary.json(atKeyPath: "url") // www.google.com
也可以拥有 JSONPrimitiveConvertible
值的数组,例如
let urlsDictionary = ["urls": ["www.google.com", "www.yahoo.com"]]
let urls: [URL] = try! urlsDictionary.json(atKeyPath: "urls") // [www.google.com, www.yahoo.com]