使用 Swift 将 Codable 结构保存到 UserDefaults
Saving a Codable Struct to UserDefaults with Swift
我正在尝试对结构进行编码
struct Configuration : Encodable, Decodable {
private enum CodingKeys : String, CodingKey {
case title = "title"
case contents = "contents"
}
var title : String?
var contents: [[Int]]?
}
到 JSON 以存储在 UserDefaults.standard 的本地密钥中。我有以下代码:
let jsonString = Configuration(title: nameField.text, contents: newContents)
let info = ["row" as String: jsonString as Configuration]
print("jsonString = \(jsonString)")
//trying to save object
let defaults = UserDefaults.standard
let recode = try! JSONEncoder().encode(jsonString)
defaults.set(recode, forKey: "simulationConfiguration")
//end of saving local
输出returns:
jsonString = Configuration(title: Optional("config"), contents: Optional([[4, 5], [5, 5], [6, 5]]))
所以我相信我正在正确创建对象。但是,当我下次 运行 模拟器尝试检索密钥时,我什么也得不到。
我将以下内容放在 AppDelegate 中,它总是 returns No Config.
let defaults = UserDefaults.standard
let config = defaults.string(forKey: "simulationConfiguration") ?? "No Config"
print("from app delegate = \(config.description)")
有什么想法吗?谢谢
encode(_:)
JSONEncoder
returns Data
的函数,而不是 String
。这意味着当您需要从 UserDefaults
取回 Configuration
时,您需要获取数据并对它们进行解码。
这是示例:
let defaults = UserDefaults.standard
guard let configData = defaults.data(forKey: "simulationConfiguration") else {
return nil // here put something or change the control flow to if statement
}
return try? JSONDecoder().decode(Configuration.self, from: configData)
- 您也不需要为
CodingKeys
中的所有案例赋值,这些值自动为案例的名称
- 如果您同时符合
Encodable
和 Decodable
,您可以简单地使用 Codable
代替,因为它是两者的组合并定义为 typealias Codable = Encodable & Decodable
您在这里保存了一个 Data
值(正确)
defaults.set(recode, forKey: "simulationConfiguration")
但是您正在阅读 String
defaults.string(forKey: "simulationConfiguration")
您无法保存 Data
,阅读 String
并期望它起作用。
让我们修复您的代码
首先,您不需要手动指定编码键。所以你的结构就变成了这个
struct Configuration : Codable {
var title : String?
var contents: [[Int]]?
}
节省
下面是保存代码
let configuration = Configuration(title: "test title", contents: [[1, 2, 3]])
if let data = try? JSONEncoder().encode(configuration) {
UserDefaults.standard.set(data, forKey: "simulationConfiguration")
}
正在加载
这是阅读它的代码
if
let data = UserDefaults.standard.value(forKey: "simulationConfiguration") as? Data,
let configuration = try? JSONDecoder().decode(Configuration.self, from: data) {
print(configuration)
}
如果您想要一个外部依赖项来避免大量的挫折,请查看 SwifterSwift
这是我使用他们的 UserDefaults 扩展分两行完成的方法。
设置:
UserDefaults.standard.set(object: configuration, forKey: "configuration")
检索对象:
guard let configuration = UserDefaults.standard.object(Configuration.self, with: "configuration") else { return }
print(configuration)
就是这样..!!
我正在尝试对结构进行编码
struct Configuration : Encodable, Decodable {
private enum CodingKeys : String, CodingKey {
case title = "title"
case contents = "contents"
}
var title : String?
var contents: [[Int]]?
}
到 JSON 以存储在 UserDefaults.standard 的本地密钥中。我有以下代码:
let jsonString = Configuration(title: nameField.text, contents: newContents)
let info = ["row" as String: jsonString as Configuration]
print("jsonString = \(jsonString)")
//trying to save object
let defaults = UserDefaults.standard
let recode = try! JSONEncoder().encode(jsonString)
defaults.set(recode, forKey: "simulationConfiguration")
//end of saving local
输出returns:
jsonString = Configuration(title: Optional("config"), contents: Optional([[4, 5], [5, 5], [6, 5]]))
所以我相信我正在正确创建对象。但是,当我下次 运行 模拟器尝试检索密钥时,我什么也得不到。 我将以下内容放在 AppDelegate 中,它总是 returns No Config.
let defaults = UserDefaults.standard
let config = defaults.string(forKey: "simulationConfiguration") ?? "No Config"
print("from app delegate = \(config.description)")
有什么想法吗?谢谢
encode(_:)
JSONEncoder
returns Data
的函数,而不是 String
。这意味着当您需要从 UserDefaults
取回 Configuration
时,您需要获取数据并对它们进行解码。
这是示例:
let defaults = UserDefaults.standard
guard let configData = defaults.data(forKey: "simulationConfiguration") else {
return nil // here put something or change the control flow to if statement
}
return try? JSONDecoder().decode(Configuration.self, from: configData)
- 您也不需要为
CodingKeys
中的所有案例赋值,这些值自动为案例的名称 - 如果您同时符合
Encodable
和Decodable
,您可以简单地使用Codable
代替,因为它是两者的组合并定义为typealias Codable = Encodable & Decodable
您在这里保存了一个 Data
值(正确)
defaults.set(recode, forKey: "simulationConfiguration")
但是您正在阅读 String
defaults.string(forKey: "simulationConfiguration")
您无法保存 Data
,阅读 String
并期望它起作用。
让我们修复您的代码
首先,您不需要手动指定编码键。所以你的结构就变成了这个
struct Configuration : Codable {
var title : String?
var contents: [[Int]]?
}
节省
下面是保存代码
let configuration = Configuration(title: "test title", contents: [[1, 2, 3]])
if let data = try? JSONEncoder().encode(configuration) {
UserDefaults.standard.set(data, forKey: "simulationConfiguration")
}
正在加载
这是阅读它的代码
if
let data = UserDefaults.standard.value(forKey: "simulationConfiguration") as? Data,
let configuration = try? JSONDecoder().decode(Configuration.self, from: data) {
print(configuration)
}
如果您想要一个外部依赖项来避免大量的挫折,请查看 SwifterSwift
这是我使用他们的 UserDefaults 扩展分两行完成的方法。
设置:
UserDefaults.standard.set(object: configuration, forKey: "configuration")
检索对象:
guard let configuration = UserDefaults.standard.object(Configuration.self, with: "configuration") else { return }
print(configuration)
就是这样..!!