2017-03-13 53 views
1

目的编码嵌套枚举SWIFT 3

我有一个状态属性的用户类,我想将其存储到NSUserDefault这就需要先进行编码的用户类别。

User类代码更新版本

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' 

回答

2

我试图编码和解码的地位,因为它是班上唯一的财产,但您可能需要其他属性做同样的如果有的话是发现

首先,我开始给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 
} 

其次,我配置了值类来实现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) 
} 

测试的结果,我也建议阅读一些关于它在这里:NSCodingWorkaround for Swift Enum with raw type + case arguments?

+0

感谢您的答复,但我仍然有错误'终止应用程序由于未捕获的异常'NSInvalidArgumentException',原因:' - [_ SwiftValue encodeWithCoder:]:无法识别的选择器发送到实例0x7f940e6bec30''在这个方法** let encodedData:Data = NSKeyedArch iver.archivedData(withRootObject:self)**这是写在用户类内 –

+1

@StephenChen我从你的错误中注意到你仍然在使用'func encodeWithCoder(aCoder:NSCoder)'而不是'public func encode(with aCoder:NSCoder) '。是这种情况还是这是你以前没有得到的新错误? – Prientus

+0

@Prientus对不起,我打错了。感谢您的通知,在我的代码中,我确实使用了'公共func编码(使用代码:NSCoder)' –