Codementor Events

Enums in Swift with Real Life Examples

Published Jan 16, 2018

Introduction

Enumeration (Enum) defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code.

func dayType(for day: String) -> String {
  switch day {
    case: "Saturday", "Sunday": return "Weekend"
    case: "Monday", "Tuesday", "Wednessday", "Thursday", "Friday": return "Weekday"
    default: return "This is not a valid date"
  }
}

let result1 = dayType(for: "Sunday") //will return "Weekend"
let result2 = dayType(for: "Thursday") //will return "Weekday"
let result3 = dayType(for: "fridayys") //will return "This is not a valid date"

Assuming we have a method named dayType that accept any day of the week then return Weekend for Saturday and Sunday, Weekday for Monday, Tuesday, Wednessday, Thursday and Friday and return This is not a valid date when it fails to recognised what was been passed into it. The function will work as aspected but what happens when you actually want to pass let say a friday but you mistakingly type fridaysy even though what we actually wanted to type was friday. The switch above goes to the default This is not a valid date. That is the type-safty enum brings into the table. It help us to avoid such risk by providing common type for group of related values like below:

enum Day {
  case Sunday
  case Monday
  case Tuesday
  case Wednessday
  case Thursday
  case Friday
  case Saturday
}

/** Rewriting the date type function */
func dayType(for day: Day) {
  switch day {
    case Day.Saturday, Day.Sunday: 
      return "Weekend"
    case Day.Monday, Day.Tuesday, Day.Wednessday, Day.Thursday, Day.Friday 
      return "Weekday"
  }
}

let result1 = dayType(for: Day.Sunday) //will return "Weekend"

We have been able to eliminate the use of String by defining an enum to hold the days. We don’t need to use the append the Day before every declaration of the day enum within the switch statement because we already assigned day to be a type of Day. Hence the dayType function can be reduce to below:

/** Rewriting the date type function */

func dayType(for day: Day) {
  switch day {
    case .Saturday, .Sunday: 
      return "Weekend"
    case .Monday, .Tuesday, .Wednessday, .Thursday, .Friday 
      return "Weekday"
  }
}

We have to understand enum is best suited for declaring types with finite sets of possible states, like Direction (north, south, west, east), Movement (Up, down, left, right) etc.

Enum Values

We can assign value to each enum case. This is useful if the enum itself indeed relates to something

// You can also map to strings
enum Week: String {
    case Sunday = "Weekday"
    case Monday = "Weekday"
    case Tuesday = "Weekday"
    case Wednessday = "Weekday"
    case Thursday = "Weekday"
    case Friday = "Weekend"
    case Saturday = "Weekend"
}

// You can also map to Int
enum Movement: Int {
    case Left = 0
    case Right = 1
    case Top = 2
    case Bottom = 3
}

// Or to floating point
enum Constants: Double {
    case π = 3.14159
    case e = 2.71828
    case φ = 1.61803398874
    case λ = 1.30357
}

We can access the value assigned to an enum with the rawValue keyword. To access the Week enum above, we can use Week.Monday.rawValue which will return Weekday.

Enum Associate Values

Associate values are a fantastic way of attaching additional information to an enum case. Say you’re writing a trade engine, there are two different possible trade types, Buy and Sell that will have a specific stock and amount. We can represent this using associate enum values like below


/** associate without labels */
enum Trade {
  case Buy(String, amount)
  case Sell(String, Int)
}

Trade.Buy("Firstbank PLC", 300)
Trade.Sell("Firstbank PLC", 700)

/** associate with labels */
enum Trade {
  case Buy(stock: String, amount: Int)
  case Sell(stock: String, amount: Int)
}

Trade.Buy(stock: "Firstbank PLC", amount: 300)
Trade.Sell(stock: "Firstbank PLC", amount: 700)

Enum Methods

We can also define methods on an enum like below

enum AppleDevice {
  case iPad
  case iPhone
  case AppleTv
  case AppleWatch
  
  func description() -> String {
    return "This is an apple device"
  }
}

AppleDevice.iPad.description()    //will return "This is an apple device"
AppleDevice.iPhone.description()  //will return "This is an apple device"

Notice the code snippet above, the func description will return “This is an apple device” for every case in the enum. To avoid this, we can make use of switch statement within the description method like below

enum AppleDevice {
    case iPad, iPhone, AppleTv, AppleWatch
    
    func description() -> String {
        switch self {
        case .iPad: return "\(self) was introduced 2006"
        case .iPhone: return "\(self) was introduced 2007"
        case .AppleTv: return "\(self) was introduced 2010"
        case .AppleWatch: return "\(self) was introduced 2014"
        }
    }
}

AppleDevice.iPad.description()    //will return "iPad was introduced 2006"
AppleDevice.iPhone.description()  //will return "iPhone was introduced 2007"

I am happy to share this article with you. If you’ve enjoyed this article, do show support by giving a few claps 👏 . Thanks for your time and make sure to follow me or drop your comment below 👇

Discover and read more posts from Abel Agoi
get started