Swift: Failable Enums with Optionals
UPDATE: Here is the cleanest solution (IMO) that was suggested so far. Of course, I still wish enums accepted optionals by default.
A few weeks ago, I wrote about a cool way to store and use multiple Segue Identifiers using Swift enums in your iOS project. As I was trying to use this pattern in a project this week in XCode 6.1, it no longer worked!
This is because in Swift 1.1, a Swift enum can no longer be initialized with an optional value by default 🙁 …
To make it work, I have to switch my enum from a simple one like this:
enum SegueIdentifier: String { case SegueToRedViewIdentifier = "SegueToRedViewIdentifier" case SegueToGreenViewIdentifier = "SegueToGreenViewIdentifier" case SegueToBlueViewIdentifier = "SegueToBlueViewIdentifier" }
To something a lot more complex with a custom failable initializer that takes in an optional value:
enum SegueIdentifier: String { case SegueToRedViewIdentifier = "SegueToRedViewIdentifier" case SegueToGreenViewIdentifier = "SegueToGreenViewIdentifier" case SegueToBlueViewIdentifier = "SegueToBlueViewIdentifier" init?(optionalRawValue: String?) { if let value = optionalRawValue { switch value { case "SegueToRedViewIdentifier": self = .SegueToRedViewIdentifier case "SegueToGreenViewIdentifier": self = .SegueToGreenViewIdentifier case "SegueToBlueViewIdentifier": self = .SegueToBlueViewIdentifier default: return nil } } return nil } }
Of course, at this point, I think it’s less painful to just do two nested if statements:
enum SegueIdentifier: String { case SegueToRedViewIdentifier = "SegueToRedViewIdentifier" case SegueToGreenViewIdentifier = "SegueToGreenViewIdentifier" case SegueToBlueViewIdentifier = "SegueToBlueViewIdentifier" } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if let segueIdentifier = segue.identifier { if let segueIdentifierValue = SegueIdentifier(rawValue: segue.identifier) { switch segueIdentifierValue { case .SegueToRedViewIdentifier: println("red") case .SegueToGreenViewIdentifier: println("green") case .SegueToBlueViewIdentifier: println("blue") } } } }
Or something not as clear / readable using the ?? operator:
enum SegueIdentifier: String { case SegueToRedViewIdentifier = "SegueToRedViewIdentifier" case SegueToGreenViewIdentifier = "SegueToGreenViewIdentifier" case SegueToBlueViewIdentifier = "SegueToBlueViewIdentifier" } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if let segueIdentifier = SegueIdentifier( rawValue: segue.identifier ?? "") { switch segueIdentifier { case .SegueToRedViewIdentifier: println("red") case .SegueToGreenViewIdentifier: println("green") case .SegueToBlueViewIdentifier: println("blue") } } }
Does anyone have a better way of handling initializing enums with optional values? I’ll make sure to file a radar!
Pingback: iOS: Working with Segues in Swift()
Pingback: Failable Enums with Optionals : Tomasz Szulc()