213

Given the following enum:

enum Audience {
    case Public
    case Friends
    case Private
}

How do I get the string "Public" from the audience constant below?

let audience = Audience.Public
7
  • 3
    please check this answer, it may give you some ideas about how you can achieve such thing: stackoverflow.com/questions/24648726/enums-with-data-in-swift/… Commented Jul 11, 2014 at 15:18
  • 1
    in Swift 2 and xcode7 you don't need to change anything to your code, just use print("\(audience)") Commented Dec 8, 2015 at 15:57
  • 8
    I hate that the Swift ecoscape is now filled with very dated answers like this. As Of XCode8.2/Swift3, it's as easy as String(describing: yourEnumValue) Commented Jan 13, 2017 at 0:09
  • @TravisGriggs It does not work for Xcode 11.4 any longer Commented Mar 4, 2020 at 5:36
  • 1
    Possible duplicate of How to get the name of enumeration value in Swift? Commented Mar 16, 2020 at 22:57

19 Answers 19

291

The idiomatic interface for 'getting a String' is to use the CustomStringConvertible interface and access the description getter. You could specify the 'raw type' as String but the use of description hides the 'raw type' implementation; avoids string comparisons in switch/case and allows for internationalization, if you so desire. Define your enum as:

enum Foo : CustomStringConvertible {
  case Bing
  case Bang
  case Boom
  
  var description : String { 
    switch self {
    // Use Internationalization, as appropriate.
    case .Bing: return "Bing"
    case .Bang: return "Bang"
    case .Boom: return "Boom"
    }
  }
}

In action:

 > let foo = Foo.Bing
foo: Foo = Bing
 > println ("String for 'foo' is \(foo)"
String for 'foo' is Bing

Updated: For Swift >= 2.0, replaced Printable with CustomStringConvertible

Note: Using CustomStringConvertible allows Foo to adopt a different raw type. For example enum Foo : Int, CustomStringConvertible { ... } is possible. This freedom can be useful.

Sign up to request clarification or add additional context in comments.

9 Comments

Another shorter way to create the println string is: "String for 'foo' is (foo)"
@JohnM.P.Knox don't forget the back-slash as in "String for 'foo' is \(foo)". Edit OK, it's the editor getting rid of it, I had to enter 2 of them in order for it to show up
What's the point in CustomStringConvertible if this works just as fine without it?
CustomStringConvertible allows/requires you to define description which lets you decide what string to use for each enum case - this is important for internationalization surely and perhaps code readability. If you don't care about those, then you can use 'enum Foo : String { /* ... */ }`
This is the correct answer if your enum is not a String or you want a different string then the rawValue. @denis631
|
248

Not sure in which Swift version this feature was added, but right now (Swift 2.1) you only need this code:

enum Audience: String {
    case public
    case friends
    case private
}

let audience = Audience.public.rawValue // "public"

You can also assign custom strings to each case:

enum Audience: String {
    case public = "The Public"
    case friends = "My Friends"
    case private = "Private Audience"
}

let audience = Audience.public.rawValue // "The Public"

When strings are used for raw values, the implicit value for each case is the text of that case’s name.

[...]

enum CompassPoint: String {
    case north, south, east, west
}

In the example above, CompassPoint.south has an implicit raw value of "south", and so on.

You access the raw value of an enumeration case with its rawValue property:

let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"

Source.

8 Comments

in xcode7.3 swift2.2, if i do things like: print("appState: \(application.applicationState)") i get appState: UIApplicationState which is the type and not the actual string representation of the enum value. Am I missing something here? (PS: for rawValue I just get the Int value...)
@Cyrus your scenario is different from that was asked in this thread. .rawValue will return the raw value of your enum. Yours is public enum UIApplicationState : Int which is indeed of type Int. You also have never read my answer which has a quote from Apple docs. ... If you still want to convert UIApplicationState to string I'd suggest you to extend UIApplicationState with a custom computed property extension UIApplicationState { var toString() -> String { /* check self for all diff. cases and return something like "Active" */ }
Doesn't solve the issue with having enums of not String type
@denis631 what do you mean? The raw type of an enum can be anything. An enum can even conform to OptionSet if you really want to. And the original question is about Strings anyways.
if my enum is written like this, enum Test: Int { case A, B }, the rawValue will of course return int back, what we are looking for is a way to get the name of the case as a String. This is exactly what @DanilShaykhutdinov did. Look at his answer and in the original question the enum has no type, not a String or Int.
|
59

In swift 3, you can use this

var enumValue = Customer.Physics
var str = String(describing: enumValue)

from Swift how to use enum to get string value

6 Comments

This is really helpful, especially if my enum is not based on Strings
"\(enumValue)" Does the same thing. ^^
This is a better answer. Doesn't require making your enum String type.
String(describing:) should never be used to convert anything to String, it's not its purpose and will give unexpected results in many cases. Better use string interpolation or string initializers.
@EricAya According to..? That's exactly what it's for: "Use this initializer to convert an instance of any type to its preferred representation as a String instance."
|
36

For now, I'll redefine the enum as:

enum Audience: String {
    case Public = "Public"
    case Friends = "Friends"
    case Private = "Private"
}

so that I can do:

audience.toRaw() // "Public"

But, isn't this new enum definition redundant? Can I keep the initial enum definition and do something like:

audience.toString() // "Public"

3 Comments

As of Xcode 7 Beta 3 you can just write your answer but without the = String because it gets automatically a raw value (name of the case) if you don't provide any.
Instead of .toString() now use .rawValue
In Swift 1.2 you can use: println(Audience.Friends.rawValue)
29

I like to use Printable with Raw Values.

enum Audience: String, Printable {
    case Public = "Public"
    case Friends = "Friends"
    case Private = "Private"

    var description: String {
        return self.rawValue
    }
}

Then we can do:

let audience = Audience.Public.description // audience = "Public"

or

println("The value of Public is \(Audience.Public)") 
// Prints "The value of Public is Public"

1 Comment

I like this way better than the selected answer because I can do Audience(rawValue: "Friends")
15

A swift 3 and above example if using Ints in Enum

public enum ECategory : Int{
        case Attraction=0, FP, Food, Restroom, Popcorn, Shop, Service, None;
        var description: String {
            return String(describing: self)
        }
    }

let category = ECategory.Attraction
let categoryName = category.description //string Attraction

2 Comments

An elegant solution. "\(category)" or directly String(describing:category) would also work. Even for Int enums.
This is my prefered solution. It allows to get the enum element's index and the associated String value
12

Updated for the release of Xcode 7 GM. It works as one would hope now--thanks Apple!

enum Rank:Int {
    case Ace = 1, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King
}

let r = Rank.Ace

print(r)               // prints "Ace"
print("Rank: \(r)!")   // prints "Rank: Ace!"

3 Comments

In Swift 2.0, conforming to CustomStringConvertible would actually allow using just print(r) in this case.
In Xcode 7 beta 4, reflect() seems to have been disabled in favor of Mirror(reflecting: x). However, the returned object has a different structure.
Update the answer please
12

It couldn't get simpler than this in Swift 2 and the latest Xcode 7 (no need to specify enum type, or .rawValue, descriptors etc...)

Updated for Swift 3 and Xcode 8:

    enum Audience {
        case Public
        case Friends
        case Private
    }

    let audience: Audience = .Public  // or, let audience = Audience.Public
    print(audience) // "Public"

10 Comments

Worked perfectly with my Int backed enums
Just an observation: This works for self created enums but doesn't work for something like HKWorkoutActivityType
As well as for localized strings ;)
The original question was about converting enum value to string in your own enums, so that's what I gave an answer for... If you'll like to handle UIKit/AppKit Enums, of course it's a different story.
@gbdavid - Is there a Q for UIKit/AppKit Enums? I googled and couldn't find it. I can submit Q if that is needed.
|
11

You can also use "\(enumVal)" Here is an example :

enum WeekDays{ case Sat, Sun, Mon, Tue, Wed, The, Fri } 

let dayOfWeek: String = "\(WeekDays.Mon)"

Tried and tested in Swift 5

Comments

8

After try few different ways, i found that if you don't want to use:

let audience = Audience.Public.toRaw()

You can still archive it using a struct

struct Audience {
   static let Public  = "Public"
   static let Friends = "Friends"
   static let Private = "Private"
}

then your code:

let audience = Audience.Public

will work as expected. It isn't pretty and there are some downsides because you not using a "enum", you can't use the shortcut only adding .Private neither will work with switch cases.

3 Comments

Looks neat. I wonder what would be the best practice for this particular case. I would prefer using the struct syntax because of the simplicity but using struct instead of enum doesn't seem right, or maybe it is just me? Well, nothing prevents you on just declaring constant variables anywhere else, this time you just add it inside a struct so its organized. Thoughts?
Exactly, It works as constant variables but more organised. As I said before the only problem is the "switch case" and the shortcuts ".Private". If you are building from scratch your app, try to go with "enum", use structs only if the "enum" doesn't satisfy your code for some reason. I'm personally avoid constants variables an always use structs instead.
I use this for default keys. Rather than remembering default keys within an app, I dump the keys in a struct and pull them from there.
8

For anyone reading the example in "A Swift Tour" chapter of "The Swift Programming Language" and looking for a way to simplify the simpleDescription() method, converting the enum itself to String by doing String(self) will do it:

enum Rank: Int
{
    case Ace = 1 //required otherwise Ace will be 0
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King
    func simpleDescription() -> String {
        switch self {
            case .Ace, .Jack, .Queen, .King:
                return String(self).lowercaseString
            default:
                return String(self.rawValue)
        }
     }
 }

1 Comment

Just be sure you aren't using the enum with "@objc". That causes this approach to fail.
6

Starting from Swift 3.0 you can

var str = String(describing: Audience.friends)

1 Comment

Unbelievable, but that perfectly works. Much shorter than "idiomatic" approach. Thanks!
5

Use Ruby way

var public: String = "\(Audience.Public)"

Comments

4

There are multiple ways to do this. Either you could define a function in the enum which returns the string based on the value of enum type:

enum Audience{
    ...
func toString()->String{
  var a:String

  switch self{
   case .Public:
    a="Public"
   case .Friends:
    a="Friends"
   ...
 }
 return a
}

Or you could can try this:

enum Audience:String{
   case Public="Public"
   case Friends="Friends"
   case Private="Private"
}

And to use it:

var a:Audience=Audience.Public
println(a.toRaw())

Comments

3

Friendly by guides if you need to use static strings as enum values:

class EncyclopediaOfCats {
    struct Constants {
        static var playHideAndSeek: String { "Play hide-and-seek" }
        static var eat: String { "Eats" }
        static var sleep: String { "Sleep" }
        static var beCute: String { "Be cute" }
    }
}

enum CatLife {
    case playHideAndSeek
    case eat
    case sleep
    case beCute

    typealias RawValue = String
    
    var rawValue: String {
        switch self {
        case .playHideAndSeek:
            return EncyclopediaOfCats.Constants.playHideAndSeek
        case .eat:
            return EncyclopediaOfCats.Constants.eat
        case .sleep:
            return EncyclopediaOfCats.Constants.sleep
        case .beCute:
            return EncyclopediaOfCats.Constants.beCute
        }
    }
    
    init?(rawValue: CatLife.RawValue) {
        switch rawValue {
        case EncyclopediaOfCats.Constants.playHideAndSeek:
            self = .playHideAndSeek
        case EncyclopediaOfCats.Constants.eat:
            self = .eat
        case EncyclopediaOfCats.Constants.sleep:
            self = .sleep
        case EncyclopediaOfCats.Constants.beCute:
            self = .beCute
        default:
            self = .playHideAndSeek
        }
    }
}

1 Comment

Why do you need to use static strings? Anyway, since you can explicitly assign raw values, couldn't you just do the following? enum CatLife: String { case playHideAndSeek = EncyclopediaOfCats.Constants.playHideAndSeek /* ... */ }
3

XCode 14.0.1/Swift 5.7:

This is something that should be simple to achieve, but that is quite confusing, with some pitfalls!

Most answers here explain how to associate strings to each enum values, or to create enums of explicit Strings, but is only possible when you are creating your own enums.

In case of enums already existing, like numerous enums in Apple's APIs, one could really want to convert enums values to String.

To take a concrete example, if one wants to display NWConnection.States values in a SwiftUI Text view.

According to some answers, and assuming that we have something like:

Class tcpClient() {
    var connection: NWConnection
    (...)

then

Text("Current state: \(tcpClient.connection.state)")

should work. But you get a "No exact matches in call to instance method 'appendInterpolation'" error.

A reason to explain this behaviour is because despite being described as enum in Apple's documentation, some enumerations are in fact not Swift enumerations, but C-Style enumerations. And according to Apple, Swift can't print the text version, because all it has at runtime is enum's number value. This could be the case for quite some APIs. See: https://stackoverflow.com/a/70910402/5965609

Other solution proposed here is:

Text(String(describing: tcpClient.connection.state))

Seems to work, but @Eric Aya comment here says : String(describing:) should never be used to convert anything to String, it's not its purpose and will give unexpected results in many cases. Better use string interpolation or string initializers.

So, in case of C-Style enumarations from APIs or other imported code, the only viable solution seems to have a function with a switch case to associate Strings to each enum's value.

2 Comments

The original question's title is "Swift: Convert enum value to String?" but most of the other answers told how to create enums with strings associated to values, so did not really answered the question. I'm discussing how to really convert enum values to String, taking a real case to illustrate it (NWConnection States but could have been anything else) and showing which pitfalls you can get into, since one of the previous answer using String interpolation doesn't work, and the other is discouraged, it seems to me that i do try to answer the question, but i do still have some doubts.
Answer edited with rewording and additionnal informations
2

One more way

public enum HTTP{
case get
case put
case delete
case patch
var value: String? {
return String(describing: self)
}

Comments

0

If you want a string representation of an existing enum, you can extend that enum with CustomStringConvertible.

e.g. I wanted to see a string version of UIGestureRecognizer.State

extension UIGestureRecognizer.State: CustomStringConvertible {
    public var description: String {
        switch self {
            case .possible:
                return "possible"
            case .began:
                return "began"
            case .changed:
                return "changed"
            case .ended:
                return "ended"
            case .cancelled:
                return "cancelled"
            case .failed:
                return "failed"
            @unknown default:
                return "default"
        }
    }
}

let state = UIGestureRecognizer.State.began

print("state: \(state)")

prints:

"state: began"

Comments

0

I agree with all the above answers but in your enum private and the public cases can't be defined since those are default keywords. I'm including CaseIterable in my answer, it may help you to get all cases if you required to loop over.

enum Audience: String, CaseIterable {
 case publicAudience
 case friends
 case privateAudience

 var description: String {
    switch self {
    case .publicAudience: return "Public"
    case .friends: return "Friends"
    case .privateAudience: return "Private"
    }
 }

 static var allAudience: [String] {
    return Audience { $0.rawValue }
 }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.