编码嵌套枚举 swift 3
Encode nested enumeration swift 3
目的
我有一个用户 class,其状态为 属性,我想将其存储到需要对用户 class 进行编码的 NSUserDefault 中第一.
用户class代码更新版本
public class User: NSObject, NSCoding {
override init() {}
var status: Status = .unKnow
required convenience public init(coder aDecoder: NSCoder) {
self.init()
self.status = aDecoder.decodeObject(forKey: "UserStatus") as? Status ?? .unKnow
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(self.status, forKey: "UserStatus")
}
public func updatePersistentData() {
let userDefault = UserDefaults.standard
/// stuck at this line
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: self)
userDefault.set(encodedData, forKey: "User")
userDefault.synchronize()
}
}
还有我的嵌套枚举
enum Status {
/// is Login status
case isLogin(style: LoginStatus)
/// is register
case isRegister(style: RegisterStatus)
/// is fetch user info
case isGetUserInfo(style: GetUserInfoStatus)
/// nonabove
case unKnow
}
enum LoginStatus: Int {
case a
case b
case c
case d
}
enum RegisterStatus: Int {
case a
case b
case c
case d
}
enum GetUserInfoStatus: Int {
case a
case b
case c
case d
}
我找到了 this,并且知道我需要将枚举转换为原始值。似乎需要使用具有字符串样式或 Int 样式的普通枚举...等
而我运行代码,错误信息
HJC[2371:403228] -[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x7f940e6bec30
HJC[2371:403228] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x7f940e6bec30'
我尝试对状态进行编码和解码,因为它是 class 中唯一的 属性,但如果找到任何其他属性,您可能需要对其他属性执行相同的操作
首先我开始给 State
枚举一个我可以编码的值
enum Status {
enum StatusValue {
case isLogin(LoginStatus)
case isRegister(RegisterStatus)
case isGetUserInfo(RegisterStatus)
case unknow
}
}
extension Status.StatusValue {
var value: Int {
switch self {
case .isLogin(let value):
return value.rawValue
case .isRegister(let value):
return value.rawValue
case .isGetUserInfo(let value):
return value.rawValue
case .unknow:
return -1
}
}
}
enum LoginStatus: Int {
case a = 0
case b
case c
case d
}
enum RegisterStatus: Int {
case a = 4
case b
case c
case d
}
enum GetUserInfoStatus: Int {
case a = 8
case b
case c
case d
}
其次,我配置了 User
class 来实现 NSCoding
public class User: NSObject, NSCoding {
override init() {
status = .unknow
}
init(_ status: Status.StatusValue) {
self.status = status
}
var status: Status.StatusValue
public func encode(with aCoder: NSCoder) {
print(self.status.value)
aCoder.encode(self.status.value, forKey: "status")
}
public required convenience init(coder aDecoder: NSCoder) {
let status = aDecoder.decodeObject(forKey: "status") as? Status.StatusValue ?? .unknow
self.init(status)
}
func save() {
let savedData = NSKeyedArchiver.archivedData(withRootObject: self)
let defaults = UserDefaults.standard
defaults.set(savedData, forKey: "user")
defaults.synchronize()
}
}
最后我通过
测试了结果
let user1: User = User()
user1.status = .isLogin(LoginStatus.b)
user1.save()
let user2: User
let defaults = UserDefaults.standard
if let saveduser = defaults.object(forKey: "user") as? Data {
user2 = NSKeyedUnarchiver.unarchiveObject(with: saveduser) as! User
print(user2)
}
我还建议在这里阅读一些相关内容:NSCoding, Workaround for Swift Enum with raw type + case arguments?
目的
我有一个用户 class,其状态为 属性,我想将其存储到需要对用户 class 进行编码的 NSUserDefault 中第一.
用户class代码更新版本
public class User: NSObject, NSCoding {
override init() {}
var status: Status = .unKnow
required convenience public init(coder aDecoder: NSCoder) {
self.init()
self.status = aDecoder.decodeObject(forKey: "UserStatus") as? Status ?? .unKnow
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(self.status, forKey: "UserStatus")
}
public func updatePersistentData() {
let userDefault = UserDefaults.standard
/// stuck at this line
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: self)
userDefault.set(encodedData, forKey: "User")
userDefault.synchronize()
}
}
还有我的嵌套枚举
enum Status {
/// is Login status
case isLogin(style: LoginStatus)
/// is register
case isRegister(style: RegisterStatus)
/// is fetch user info
case isGetUserInfo(style: GetUserInfoStatus)
/// nonabove
case unKnow
}
enum LoginStatus: Int {
case a
case b
case c
case d
}
enum RegisterStatus: Int {
case a
case b
case c
case d
}
enum GetUserInfoStatus: Int {
case a
case b
case c
case d
}
我找到了 this,并且知道我需要将枚举转换为原始值。似乎需要使用具有字符串样式或 Int 样式的普通枚举...等
而我运行代码,错误信息
HJC[2371:403228] -[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x7f940e6bec30
HJC[2371:403228] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x7f940e6bec30'
我尝试对状态进行编码和解码,因为它是 class 中唯一的 属性,但如果找到任何其他属性,您可能需要对其他属性执行相同的操作
首先我开始给 State
枚举一个我可以编码的值
enum Status {
enum StatusValue {
case isLogin(LoginStatus)
case isRegister(RegisterStatus)
case isGetUserInfo(RegisterStatus)
case unknow
}
}
extension Status.StatusValue {
var value: Int {
switch self {
case .isLogin(let value):
return value.rawValue
case .isRegister(let value):
return value.rawValue
case .isGetUserInfo(let value):
return value.rawValue
case .unknow:
return -1
}
}
}
enum LoginStatus: Int {
case a = 0
case b
case c
case d
}
enum RegisterStatus: Int {
case a = 4
case b
case c
case d
}
enum GetUserInfoStatus: Int {
case a = 8
case b
case c
case d
}
其次,我配置了 User
class 来实现 NSCoding
public class User: NSObject, NSCoding {
override init() {
status = .unknow
}
init(_ status: Status.StatusValue) {
self.status = status
}
var status: Status.StatusValue
public func encode(with aCoder: NSCoder) {
print(self.status.value)
aCoder.encode(self.status.value, forKey: "status")
}
public required convenience init(coder aDecoder: NSCoder) {
let status = aDecoder.decodeObject(forKey: "status") as? Status.StatusValue ?? .unknow
self.init(status)
}
func save() {
let savedData = NSKeyedArchiver.archivedData(withRootObject: self)
let defaults = UserDefaults.standard
defaults.set(savedData, forKey: "user")
defaults.synchronize()
}
}
最后我通过
测试了结果let user1: User = User()
user1.status = .isLogin(LoginStatus.b)
user1.save()
let user2: User
let defaults = UserDefaults.standard
if let saveduser = defaults.object(forKey: "user") as? Data {
user2 = NSKeyedUnarchiver.unarchiveObject(with: saveduser) as! User
print(user2)
}
我还建议在这里阅读一些相关内容:NSCoding, Workaround for Swift Enum with raw type + case arguments?