How to get enum from raw value in Swift?
With Swift 4.2 and CaseIterable protocol it is not that hard at all!
Here is an example of how to implement it.
import UIKit
private enum DataType: String, CaseIterable {
case someDataOne = "an_awesome_string_one"
case someDataTwo = "an_awesome_string_two"
case someDataThree = "an_awesome_string_three"
case someDataFour = "an_awesome_string_four"
func localizedString() -> String {
// Internal operation
// I have a String extension which returns its localized version
return self.rawValue.localized
}
static func fromLocalizedString(localizedString: String) -> DataType? {
for type in DataType.allCases {
if type.localizedString() == localizedString {
return type
}
}
return nil
}
}
// USAGE EXAMPLE
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let dataType = DataType.fromLocalizedString(localizedString: self.title) {
loadUserData(type: dataType)
}
}
You can easily modify it to return the DataType based on the rawValue. I hope it helps!
Too complicated, just assign the raw values directly to the cases
enum TestEnum: String {
case Name = "Name"
case Gender = "Gender"
case Birth = "Birth Day"
}
let name = TestEnum(rawValue: "Name")! //Name
let gender = TestEnum(rawValue: "Gender")! //Gender
let birth = TestEnum(rawValue: "Birth Day")! //Birth
If the case name matches the raw value you can even omit it
enum TestEnum: String {
case Name, Gender, Birth = "Birth Day"
}
In Swift 3+ all enum cases are lowercased
You can define enum like this -
enum TestEnum: String {
case Name, Gender, Birth
}
OR
enum TestEnum: String {
case Name
case Gender
case Birth
}
you can provide an init method which defaults to one of the member values.
enum TestEnum: String {
case Name, Gender, Birth
init() {
self = .Gender
}
}
In the example above, TestEnum.Name has an implicit raw value of "Name", and so on.
You access the raw value of an enumeration case with its rawValue property:
let testEnum = TestEnum.Name.rawValue
// testEnum is "Name"
let testEnum1 = TestEnum()
// testEnum1 is "Gender"
Full working example:
enum TestEnum: String {
case name = "A Name"
case otherName
case test = "Test"
}
let first: TestEnum? = TestEnum(rawValue: "A Name")
let second: TestEnum? = TestEnum(rawValue: "OtherName")
let third: TestEnum? = TestEnum(rawValue: "Test")
print("\(first), \(second), \(third)")
All of those will work, but when initializing using a raw value it will be an optional. If this is a problem you could create an initializer or constructor for the enum to try and handle this, adding a none
case and returning it if the enum couldn't be created. Something like this:
static func create(rawValue:String) -> TestEnum {
if let testVal = TestEnum(rawValue: rawValue) {
return testVal
}
else{
return .none
}
}