struct User {
let firstName: String
let lastName: String
}
当处理这样的数据时,Swift 为我们提供了一个奇妙的协议,称为Codable:专门用于归档和取消归档数据的协议,这是“将对象转换为纯文本并再次转换回来”的一种奇特方式。
我们想要存档自定义类型,以便我们可以将其放入 UserDefaults中,然后在它从UserDefaults 返回时取消存档
- 遵守协议
遵守协议后,Swift 会自动为我们生成一些代码,根据需要为我们归档和取消归档User实例
struct User: Codable {
let firstName: String
let lastName: String
}
- 归档:将对象数据 转换为 JSON 数据
if let data = try? JSONEncoder().encode(user) {
UserDefaults.standard.set(data, forKey: "UserData")
}
使用的
JSONEncoder().encode()意思是“创建一个编码器并使用它来编码某些内容”,这一切都在一个步骤中,而不是先创建编码器然后再使用它。
这可能会引发错误,因此应该使用try或try?来调用它以巧妙地处理错误。
- 解档
if let data = UserDefaults.standard.data(forKey: "xxxKey") {
if let decData = try? JSONDecoder().decode([ExpenseItem].self, from: data){
items = decData
return
}
}
其中,decode方法需要传入 解档数据的类型
JSON嵌套
解码稍微复杂的 JSON:一个数组位于另一个数组中,使用不同的数据类型。如果您想解码这种分层数据,关键是为每个级别创建单独的类型。只要数据与您要求的层次结构相匹配,Codable就能够解码所有内容,而无需我们进行进一步的工作。
如下数据:
{
"name": "Taylor Swift",
"address": {
"street": "555, Taylor Swift Avenue",
"city": "Nashville"
}
}
创建两个结构体,并且均遵守Codable协议
struct User: Codable {
let name: String
let address: Address
}
struct Address: Codable {
let street: String
let city: String
}
接着,处理数据。先将 JSON 字符串转换为类型Data(这是Codable适用的),然后将其解码为User实例:
let data = Data(jsonString.utf8)
let decoder = JSONDecoder()
if let user = try? decoder.decode(User.self, from: data) {
print(user.address.street)
}