How to get enum from raw value in Swift?

77,606

Solution 1

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

Solution 2

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
        }
    }

Solution 3

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!

Solution 4

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"

Solution 5

Display the rawvalue using Enum

import UIKit

enum car: String {
    case bmw =  "BMW"
    case jaquar = "JAQUAR"
    case rd = "RD"
    case benz = "BENZ"

}


class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        label.text = car.bmw.rawValue

    }


}
Share:
77,606
Leo
Author by

Leo

Updated on December 04, 2021

Comments

  • Leo
    Leo over 2 years

    I'm trying to get enum type from raw value:

    enum TestEnum: String {
        case Name
        case Gender
        case Birth
    
        var rawValue: String {
            switch self {
            case .Name: return "Name"
            case .Gender: return "Gender"
            case .Birth: return "Birth Day"
            }
        }
    }
    
    let name = TestEnum(rawValue: "Name")       //Name
    let gender = TestEnum(rawValue: "Gender")   //Gender
    

    But it seems that rawValue doesn't work for string with spaces:

    let birth = TestEnum(rawValue: "Birth Day") //nil
    

    Any suggestions how to get it?

  • matt
    matt about 8 years
    Except that the variables name and so on are now Optionals, which is not likely to be what the OP wants.
  • Marcus Rossel
    Marcus Rossel about 8 years
    There is no other way, than receiving back an optional (unless you want a crash, when a string is passed, that does not correspond to an enum case).
  • vadian
    vadian about 8 years
    @matt - right, but since you know the case names at compile time you can safely unwrap the optionals. I edited the answer.
  • matt
    matt about 8 years
    Excellent. I think the OP will find that more useful!
  • keshav vishwkarma
    keshav vishwkarma about 8 years
    @matt super, compile time checking is more powerful to prevent the runtime crashes
  • Hugo
    Hugo over 7 years
    Force unwrapping an enum created from it's RawValue can cause runtime exceptions. It would be better to use the "if let" construction to unwrap the value. Also see: Apple Enum Raw Value documentation
  • vadian
    vadian over 7 years
    @Hugo You are right if the raw value is a user defined variable. On the other hand the number of enum cases cannot be changed at runtime and the developer (you) knows the values. So if the raw value to initialize the enum is a literal string the runtime error reveals a design error.
  • bbjay
    bbjay about 6 years
    init(_ str: String) { self = TestEnum(rawValue: str) ?? .none } as an additional init does the same
  • GetSwifty
    GetSwifty about 6 years
    That's another option. Personally I prefer to avoid inits with the same Typed params if possible.
  • Leo
    Leo about 5 years
    I believe there is something wrong with the design if it's required to restore an enum case from a localized string.
  • BelfDev
    BelfDev about 5 years
    @Leo, it's totally OK to discuss whether the retrieval of enum case from a localized string is ideal or not. In fact, I personally agree with you that it is not -- but sometimes we work in huge projects where we cannot simply go ahead and change anything we want. That said, I think you will agree with me when I say that this kind of discussion is out of scope... The whole point is that you can retrieve enum cases from any given associated type. It answers your initial question from 2016. Cheers!
  • Mattie
    Mattie over 2 years
    The most helpful answers are usually code and an explanation of how/why the code is used. You aren't wrong here, but a little more effort would help make this a high quality answer.