Search code examples
iosswiftnsuserdefaults

How to save Enum to UserDefaults?


I'm trying to save an enum to UserDefaults but can't successfully do that because in the do try catch I get an error. I figured out it has todo with my enum, because when I remove the enum thing in my class it works normal like before.

class User: NSObject, NSCoding {

    private(set) public var loginType: LoginType
    // some other properties

    init(name: String, username: String, email: String, profileImage: UIImage?) {
        // some other inits
        self.loginType = .email
    }

    init(name: String, username: String, telephoneNumber: String, profileImage: UIImage?) {
        // some other inits
        self.loginType = .telephoneNumber
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(self.loginType, forKey: LOGIN_TYPE_KEY)
    }

    required init?(coder aDecoder: NSCoder) {
        self.loginType = aDecoder.decodeObject(forKey: LOGIN_TYPE_KEY) as! LoginType
    }
}

here is my enum:

enum LoginType: String {
    case email = "email"
    case telephoneNumber = "telephoneNumber"
}

Solution

  • You have to save the rawValue of the enum

    func encode(with aCoder: NSCoder) {
        aCoder.encode(self.loginType.rawValue, forKey: LOGIN_TYPE_KEY)
    }
    
    required init?(coder aDecoder: NSCoder) {
        let loginRaw = aDecoder.decodeObject(forKey: LOGIN_TYPE_KEY) as! String
        self.loginType = LoginType(rawValue: loginRaw)!
    }
    

    Consider to use Codable instead of NSCoding. You don't need a subclass of NSObject and a RawRepresentable enum can be serialized directly.

    If the raw values match the cases the enum can be declared much shorter

    enum LoginType: String {
      case email, telephoneNumber
    }