Codable 是 Swift 引入的全新的编解码库,使开发者更方便的解析JSON 或 plist 文件。支持枚举、结构体和类。
Codable协议定义
Codable代表一个同时符合 Decodable 和 Encodable 协议的类型,即可解码且可编码的类型。
typealias Codable = Decodable & Encodable
public protocol Decodable {
public init(from decoder: Decoder) throws
}
public protocol Encodable {
public func encode(to encoder: Encoder) throws
}
Codable从 Swift 4 开始引入,包含了 Encoder 和 Decoder 协议和他们的两个实现 JSONEncoder、JSONDecoder 和 PropertyListEncoder、PropertyListDecoder。
其中 Codable 及其相关协议放在了标准库中,而具体的 Encoder、Decoder 类放在了 Foundation 框架中。
JSON 和 模型的相互转换
苹果提供了 JSONEncoder
和 JSONDecoder
这两个结构体来方便得在 JSON 数据和自定义模型之间互相转换。苹果可以利用一些系统私有的机制来实现转换,而不需要通过 OC Runtime
。
只要让自己的数据类型符合 Codable 协议,就可以用系统提供的编解码器进行编解码。
struct User: Codable {
var name: String
var age: Int
}
解码(JSON Data -> Model):
let user = JSONDecoder().decode(User.self, from: jsonData)
编码(Model -> JSON Data):
let jsonData = JSONEncoder().encode(user)
字典 和 模型的相互转换
将模型用JSONEncoder的encode转成Data,然后再用JSONSerialization反序列化成Dictionary对象。
struct User: Codable {
var name: String?
var age: Int?
static func convertFromDict(dict: NSDictionary) -> User? {
var user: User?
do {
let data = try JSONSerialization.data(withJSONObject: dict, options: [])
let decoder = JSONDecoder()
user = try decoder.decode(User.self, from: data)
} catch {
print(error)
}
return user
}
func convertToDict() -> NSDictionary? {
var dict: NSDictionary?
do {
let encoder = JSONEncoder()
let data = try encoder.encode(self)
dict = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary
} catch {
print(error)
}
return dict
}
}
可选链中的问号(?)和叹号(!)区别
obj.school!.dept!.name
使用感叹号(!)访问时,一旦链条某些环节没有值,程序就会发生异常。
obj.school?.dept?.name
使用问号(?)访问时,当某些环节没有值的时候返回nil,程序不会发生异常。