在 NSUserDefaults 中存储嵌套对象
Storing nested objects in NSUserDefaults
我正在尝试存储具有变异 属性 的自定义可编码结构,但我总是得到 nil
属性。
例如,具有可编码结构:
struct Test1: Codable {
var testDate: Date? = nil
let name: String
let age: Int
enum CodingKeys: String, CodingKey {
case name
case age
}
}
使用以下示例 JSON 我们将解码提供的结构,并分配自定义 属性 testDate
:
let json = """
{
"name": "test",
"age": 30,
}
"""
let jsonData = Data(json.utf8)
var test1 = try? JSONDecoder().decode(Test1.self, from: jsonData)
test1?.testDate = Date()
然后我们将尝试将此结构存储在 userDefaults:
var currentTest: Test1? {
get {
let defaults = UserDefaults.standard
guard let testData = defaults.object(forKey: "test1") as? Data,
let test = try? PropertyListDecoder().decode(Test1.self,
from: testData) else {
return nil
}
return test
}
set {
let defaults = UserDefaults.standard
defaults.set(try? PropertyListEncoder().encode(newValue), forKey: "test1")
}
}
虽然这适用于所有可编码属性,但当我尝试访问自定义 属性 时,例如 testDate
我得到的是 nil:
currentTest?.testDate = nil
有没有办法存储 "nested" 属性而不将它们作为单独的实例存储在 UserDefautls 中?
要点示例 - https://gist.github.com/ignotusverum/0cb9b57eef021eed3680530df519cedf
因为你在Test1中有CodingKeys
,你需要添加case testDate
否则属性 testDate在解码实例时会被省略。
struct Test1: Codable {
var testDate: Date? = nil
let name: String
let age: Int
enum CodingKeys: String, CodingKey {
case name
case age
case testDate
}
}
勾选Encoding and Decoding Custom Types,
...Codable types can declare a special nested enumeration named CodingKeys that conforms to the CodingKey protocol. When this enumeration is present, its cases serve as the authoritative list of properties that MUST be included when instances of a codable type are encoded or decoded. The names of the enumeration cases should match the names you've given to the corresponding properties in your type.
我正在尝试存储具有变异 属性 的自定义可编码结构,但我总是得到 nil
属性。
例如,具有可编码结构:
struct Test1: Codable {
var testDate: Date? = nil
let name: String
let age: Int
enum CodingKeys: String, CodingKey {
case name
case age
}
}
使用以下示例 JSON 我们将解码提供的结构,并分配自定义 属性 testDate
:
let json = """
{
"name": "test",
"age": 30,
}
"""
let jsonData = Data(json.utf8)
var test1 = try? JSONDecoder().decode(Test1.self, from: jsonData)
test1?.testDate = Date()
然后我们将尝试将此结构存储在 userDefaults:
var currentTest: Test1? {
get {
let defaults = UserDefaults.standard
guard let testData = defaults.object(forKey: "test1") as? Data,
let test = try? PropertyListDecoder().decode(Test1.self,
from: testData) else {
return nil
}
return test
}
set {
let defaults = UserDefaults.standard
defaults.set(try? PropertyListEncoder().encode(newValue), forKey: "test1")
}
}
虽然这适用于所有可编码属性,但当我尝试访问自定义 属性 时,例如 testDate
我得到的是 nil:
currentTest?.testDate = nil
有没有办法存储 "nested" 属性而不将它们作为单独的实例存储在 UserDefautls 中?
要点示例 - https://gist.github.com/ignotusverum/0cb9b57eef021eed3680530df519cedf
因为你在Test1中有CodingKeys
,你需要添加case testDate
否则属性 testDate在解码实例时会被省略。
struct Test1: Codable {
var testDate: Date? = nil
let name: String
let age: Int
enum CodingKeys: String, CodingKey {
case name
case age
case testDate
}
}
勾选Encoding and Decoding Custom Types,
...Codable types can declare a special nested enumeration named CodingKeys that conforms to the CodingKey protocol. When this enumeration is present, its cases serve as the authoritative list of properties that MUST be included when instances of a codable type are encoded or decoded. The names of the enumeration cases should match the names you've given to the corresponding properties in your type.