Adr*_*ian 5 nsuserdefaults swift codable
跟进我之前的问题:
我设法使我的枚举符合 Codable 协议,实现了 init() 和encode(),它似乎可以工作。
enum UserState {
case LoggedIn(LoggedInState)
case LoggedOut(LoggedOutState)
}
enum LoggedInState: String {
case playing
case paused
case stopped
}
enum LoggedOutState: String {
case Unregistered
case Registered
}
extension UserState: Codable {
enum CodingKeys: String, CodingKey {
case loggedIn
case loggedOut
}
enum CodingError: Error {
case decoding(String)
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
if let loggedIn = try? values.decode(String.self, forKey: .loggedIn) {
self = .LoggedIn(LoggedInState(rawValue: loggedIn)!)
}
else if let loggedOut = try? values.decode(String.self, forKey: .loggedOut) {
self = .LoggedOut(LoggedOutState(rawValue: loggedOut)!)
}
else {
throw CodingError.decoding("Decoding failed")
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case let .LoggedIn(value):
try container.encode(value.rawValue, forKey: .loggedIn)
case let .LoggedOut(value):
try container.encode(value.rawValue, forKey: .loggedOut)
}
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let state = UserState.LoggedIn(.playing)
UserDefaults.standard.set(state, forKey: "state")
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是我不知道如何将其保存到 UserDefaults。如果我像现在一样保存它,我在运行应用程序时会收到以下错误:
[User Defaults] Attempt to set a non-property-list object Codable.UserState.LoggedIn(Codable.LoggedInState.playing) as an NSUserDefaults/CFPreferences value for key state
2018-01-20 19:06:26.909349+0200 Codable[6291:789687]
Run Code Online (Sandbox Code Playgroud)
来自UserDefaults参考:
\n\n\n默认对象必须是属性列表\xe2\x80\x94,即NSData、 NSString、\n NSNumber、NSDate、NSArray 或 NSDictionary的实例(或\n 对于集合,是实例的组合) 。如果要存储任何其他类型的对象,通常应该将其存档以创建 NSData 实例。
\n
因此,您应该state手动编码并将其存储为数据:
if let encoded = try? JSONEncoder().encode(state) {\n UserDefaults.standard.set(encoded, forKey: "state")\n}\nRun Code Online (Sandbox Code Playgroud)\n\n然后,读回它:
\n\nguard let data = UserDefaults.standard.data(forKey: "state") else { fatalError() }\nif let saved = try? JSONDecoder().decode(UserState.self, from: data) {\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1913 次 |
| 最近记录: |