I have an enum like this:
enum Environment { case Production case Staging case Dev }
And I'd like to save an instance in NSUserDefaults like this:
func saveEnvironment(environment : Environment){ NSUserDefaults.standardUserDefaults().setObject(environment, forKey: kSavedEnvironmentDefaultsKey) }
I understand that a Swift enum isn't an NSObject, and that makes it difficult to save, but I'm unsure what the best way is to convert it to something storable.
Storing the Raw Value It isn't possible to store an enum in the user's defaults database. We need to convert the value to a type that is supported by the defaults system. The easiest solution is to ask the enum for its raw value and store that value in the user's defaults database.
In Swift language, we have Structs, Enum and Classes. Struct and Enum are passed by copy but Classes are passed by reference. Only Classes support inheritance, Enum and Struct don't.
From what I understand, you can only import Swift stuff in . m files and there is no way to forward declare an enum in Objective C.
In Swift, we can also assign values to each enum case. For example, enum Size : Int { case small = 10 case medium = 12 ... } Here, we have assigned values 29 and 31 to enum cases small and medium respectively.
Using rawValue for the enum is one way of using types that can be stored in NSUserDefaults, define your enum to use a rawValue. Raw values can be strings, characters, or any of the integer or floating-point number types :
enum Environment: String { case Production = "Prod" case Staging = "Stg" case Dev = "Dev" }
You can also create an enum instance directly using the rawValue (which could come from NSUserDefaults) like:
let env = Environment(rawValue: "Dev")
You can extract the rawValue (String) from the enum object like this and then store it in NSUserDefaults if needed:
if let myEnv = env { println(myEnv.rawValue) } func saveEnvironment(environment : Environment){ NSUserDefaults.standardUserDefaults().setObject(environment.rawValue, forKey: kSavedEnvironmentDefaultsKey) }
If you would like to save/read data from UserDefaults and separate some logic, you can do it in following way (Swift 3):
enum Environment: String { case Production case Staging case Dev } class UserDefaultsManager { static let shared = UserDefaultsManager() var environment: Environment? { get { guard let environment = UserDefaults.standard.value(forKey: kSavedEnvironmentDefaultsKey) as? String else { return nil } return Environment(rawValue: environment) } set(environment) { UserDefaults.standard.set(environment?.rawValue, forKey: kSavedEnvironmentDefaultsKey) } } }
So saving data in UserDefaults will look this way:
UserDefaultsManager.shared.environment = Environment.Production
And reading data, saved in UserDefaults in this way:
if let environment = UserDefaultsManager.shared.environment { //you can do some magic with this variable } else { print("environment data not saved in UserDefaults") }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With