JSONUtilities
轻松加载JSON对象并将它们解码为结构体或类。函数json(atKeyPath>:
从常量或变量定义中推断类型进行解码,这意味着无需进行强制类型转换。解码JSON时既支持字符串键,也支持键路径(点..
分隔的键)。
- 查看
JSONUtilities.xcodeproj
中的Example.playground
以获取工作示例
安装
CocoaPods
将pod 'JSONUtilities'
行添加到Podfile。
Carthage
将github "lucianomarisi/JSONUtilities"
行添加到Cartfile。
手动
将Sources
文件夹中的文件添加到您的Xcode项目中。
Swift包管理器
将.Package(url: "https://github.com/lucianomarisi/JSONUtilities", majorVersion: 3)
行添加到您的Package.swift。
支持的类型
JSON原始类型
Int
双精度浮点数
单精度浮点数
字符串
布尔值
[String: AnyObject]
RawRepresentable
枚举
JSON原生类型数组
[Int]
[Double]
[Float]
[String]
[Bool]
[[String: AnyObject]]
[RawRepresentable]
自定义JSON对象和自定义JSON对象数组
例如,如果 MyClass
和 MyStruct
遵循 JSONObjectConvertible
协议
MyClass
- [
MyClass
] MyStruct
- [
MyStruct
]
带有字符串键的类型化字典
[String: JSONRawType]
[String: JSONObjectConvertible]
[String: JSONPrimitiveConvertible]
[String: RawRepresentable]
InvalidItemBehaviour
在解码数组或字典时,可以传递一个 invalidItemBehaviour
参数来控制在解码子项时错误发生时的情况
.remove
这将简单地从数组或字典中删除项。这是默认操作.fail
如果任何一个子项遇到错误,整个数组或字典的解码将失败。对于可选属性,这意味着数组或字典将返回 nil,而对于非可选属性,它将抛出错误.value(T)
提供一个替代值.custom((DecodingError) -> InvalidItemBehaviour)
允许您根据特定的 DecodingError 指定行为
JSON加载示例
从文件
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解码示例
考虑一个表示人员的JSON对象
{
"name" : "John Doe",
"age" : 24,
"weight" : 72.4
}
解码内联JSON
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")
}
}
通过遵守JSONObjectConvertible协议来解码嵌套结构体或类
考虑一个公司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
接口来支持自定义原始类型
通过遵循 任何类型都可以扩展 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]