How to get the name of enumeration value in Swift? How to get the name of enumeration value in Swift? swift swift

How to get the name of enumeration value in Swift?


As of Xcode 7 beta 5 (Swift version 2) you can now print type names and enum cases by default using print(_:), or convert to String using String's init(_:) initializer or string interpolation syntax. So for your example:

enum City: Int {    case Melbourne = 1, Chelyabinsk, Bursa}let city = City.Melbourneprint(city)// prints "Melbourne"let cityName = "\(city)"   // or `let cityName = String(city)`// cityName contains "Melbourne"

So there is no longer a need to define & maintain a convenience function that switches on each case to return a string literal. In addition, this works automatically for any enum, even if no raw-value type is specified.

debugPrint(_:) & String(reflecting:) can be used for a fully-qualified name:

debugPrint(city)// prints "App.City.Melbourne" (or similar, depending on the full scope)let cityDebugName = String(reflecting: city)// cityDebugName contains "App.City.Melbourne"

Note that you can customise what is printed in each of these scenarios:

extension City: CustomStringConvertible {    var description: String {        return "City \(rawValue)"    }}print(city)// prints "City 1"extension City: CustomDebugStringConvertible {    var debugDescription: String {        return "City (rawValue: \(rawValue))"    }}debugPrint(city)// prints "City (rawValue: 1)"

(I haven't found a way to call into this "default" value, for example, to print "The city is Melbourne" without resorting back to a switch statement. Using \(self) in the implementation of description/debugDescription causes an infinite recursion.)


The comments above String's init(_:) & init(reflecting:) initializers describe exactly what is printed, depending on what the reflected type conforms to:

extension String {    /// Initialize `self` with the textual representation of `instance`.    ///    /// * If `T` conforms to `Streamable`, the result is obtained by    ///   calling `instance.writeTo(s)` on an empty string s.    /// * Otherwise, if `T` conforms to `CustomStringConvertible`, the    ///   result is `instance`'s `description`    /// * Otherwise, if `T` conforms to `CustomDebugStringConvertible`,    ///   the result is `instance`'s `debugDescription`    /// * Otherwise, an unspecified result is supplied automatically by    ///   the Swift standard library.    ///    /// - SeeAlso: `String.init<T>(reflecting: T)`    public init<T>(_ instance: T)    /// Initialize `self` with a detailed textual representation of    /// `subject`, suitable for debugging.    ///    /// * If `T` conforms to `CustomDebugStringConvertible`, the result    ///   is `subject`'s `debugDescription`.    ///    /// * Otherwise, if `T` conforms to `CustomStringConvertible`, the result    ///   is `subject`'s `description`.    ///    /// * Otherwise, if `T` conforms to `Streamable`, the result is    ///   obtained by calling `subject.writeTo(s)` on an empty string s.    ///    /// * Otherwise, an unspecified result is supplied automatically by    ///   the Swift standard library.    ///    /// - SeeAlso: `String.init<T>(T)`    public init<T>(reflecting subject: T)}


See the release notes for info about this change.


There is no introspection on enum cases at the moment. You will have to declare them each manually:

enum City: String, CustomStringConvertible {    case Melbourne = "Melbourne"    case Chelyabinsk = "Chelyabinsk"    case Bursa = "Bursa"    var description: String {        get {            return self.rawValue        }    }}

If you need the raw type to be an Int, you will have to do a switch yourself:

enum City: Int, CustomStringConvertible {  case Melbourne = 1, Chelyabinsk, Bursa  var description: String {    get {      switch self {        case .Melbourne:          return "Melbourne"        case .Chelyabinsk:          return "Chelyabinsk"        case .Bursa:          return "Bursa"      }    }  }}


In Swift-3 (tested with Xcode 8.1) you can add the following methods in your enum:

/** * The name of the enumeration (as written in case). */var name: String {    get { return String(describing: self) }}/** * The full name of the enumeration * (the name of the enum plus dot plus the name as written in case). */var description: String {    get { return String(reflecting: self) }}

You can then use it as a normal method call on your enum instance.It might also work in previous Swift versions, but I haven't tested it.

In your example:

enum City: Int {    case Melbourne = 1, Chelyabinsk, Bursa    var name: String {        get { return String(describing: self) }    }    var description: String {        get { return String(reflecting: self) }    }}let city = City.Melbourneprint(city.name)// prints "Melbourne"print(city.description)// prints "City.Melbourne"

If you want to provide this functionality to all your enums, you can make it an extension:

/** * Extend all enums with a simple method to derive their names. */extension RawRepresentable where RawValue: Any {  /**   * The name of the enumeration (as written in case).   */  var name: String {    get { return String(describing: self) }  }  /**   * The full name of the enumeration   * (the name of the enum plus dot plus the name as written in case).   */  var description: String {    get { return String(reflecting: self) }  }}

This only works for Swift enums.