If I have an enumeration with raw Integer
values:
enum City: Int {
case Melbourne = 1, Chelyabinsk, Bursa
}
let city = City.Melbourne
For Objective-C enum
s the only way currently seems to be, for example, to extend the enum with CustomStringConvertible
ending up with something like:
extension UIDeviceBatteryState: CustomStringConvertible {
public var description: String {
switch self {
case .Unknown:
return "Unknown"
case .Unplugged:
return "Unplugged"
case .Charging:
return "Charging"
case .Full:
return "Full"
}
}
}
And then casting the enum
as String
:
String(UIDevice.currentDevice().batteryState)
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.Melbourne
print(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.
This is so disappointing.
For the case when you need those names (that the compiler perfectly knows the exact spelling of, but refuses to let access -- thank you Swift team!! --) but do not want or cannot make String the base of your enum, a verbose, cumbersome alternative is as follows:
enum ViewType : Int, Printable {
case Title
case Buttons
case View
static let all = [Title, Buttons, View]
static let strings = ["Title", "Buttons", "View"]
func string() -> String {
return ViewType.strings[self.rawValue]
}
var description:String {
get {
return string()
}
}
}
You can use the above as follows:
let elementType = ViewType.Title
let column = Column.Collections
let row = 0
println("fetching element \(elementType), column: \(column.string()), row: \(row)")
And you'll get the expected result (code for the Column similar, but not shown)
fetching element Title, column: Collections, row: 0
In the above, I have made the description
property refer back to the string
method, but this is a matter of taste. Also note that so called static
variables need to be scope qualified by the name of their enclosing type, as the compiler is too amnesic and cannot recall the context all by itself...
The Swift team must really be commanded. They created enum that you cannot enumerate
and that which you can use enumerate
on are "Sequences" but not enum
!
I bumped into this question and wanted to share a simple way to create the magicFunction mentioned
enum City: Int {
case Melbourne = 1, Chelyabinsk, Bursa
func magicFunction() -> String {
return "\(self)"
}
}
let city = City.Melbourne
city.magicFunction() //prints Melbourne
Simple but works...
enum ViewType : Int {
case Title
case Buttons
case View
}
func printEnumValue(enum: ViewType) {
switch enum {
case .Title: println("ViewType.Title")
case .Buttons: println("ViewType.Buttons")
case .View: println("ViewType.View")
}
}
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"
}
}
}
}