o7planning

Swift Enums Tutorial with Examples

  1. What is Swift Enum?
  2. Get all elements of Enum
  3. Enum in switch statement
  4. Enum with Raw values
  5. Enum with Associated Values
  6. Methods in enum

1. What is Swift Enum?

In Swift, use the enum keyword to define a Enumeration with a fixed number and pre-list of elements , you can not add or remove the number of elements. For example, you can define a set day of the week (Monday, Tues, ..., Sunday).
Without enum, to have a set day of the week, you can define 7 constants representing 7 weekdays.
WeekDayConstants.swift
import Foundation 

// Defines the constants are the days of the week.  
let CONST_MONDAY = 2;
let CONST_TUESDAY = 3;
let CONST_WEDNESDAY = 4;
let CONST_THURSDAY = 5; 
let CONST_FRIDAY = 6;
let CONST_SATURDAY = 7;
let CONST_SUNDAY = 1;
A function returns the job todo in each specific day of week. (Kind of a timetable).
GetJobByDay.swift
import Foundation

// Input parameter is the day of the week.
// Returns name of Job will do 
func getJobByDay(dayInWeek: Int) -> String { 
    if (dayInWeek == CONST_SATURDAY
        || dayInWeek == CONST_SUNDAY) {
        return "Nothing";
    }
    return "Coding"; 
}
It is obvious that such code lines are not safe. For example, you call getJobByDay(Int) function, but the input parameter does not belong to a defined set.
  • No Type-Safety: First of all it’s not type-safe; you can pass any valid int value to dayInWeek
  • No Meaningful Printing: printing value of any of these constant will print its numeric value instead of meaningful name of day e.g. when you print MONDAY it will print "2" instead of "MONDAY"
And this is the way to create enum, which is a special collection.
WeekDay.swift
import Foundation

// Define an Enumeration.
enum WeekDay {
    // Elements
    case MONDAY
    case TUESDAY
    case WEDNESDAY
    case THURSDAY
    case FRIDAY
    case SATURDAY
    case SUNDAY 
}
For example, using Enum:
WeekDayTest.swift
import Foundation 

// Returns name of Job will do.
func getJob(weekDay: WeekDay) -> String  { 
    if (weekDay == WeekDay.SATURDAY || weekDay == WeekDay.SUNDAY) { 
        return "Nothing" 
    }
    return "Coding" 
} 
func test_getJob()   { 
    var weekDay = WeekDay.TUESDAY 
    print("Day = \(weekDay)")
    
    var job = getJob(weekDay) 
    print("Job = \(job)") 
}

2. Get all elements of Enum

There is not available function or method that allows you to retrieve a list of the elements of any Enum, but you can define a variable that contains all the elements of the Enum.
This example defines a Enum, in Enum also defines a constant that contains all the elements of this Enum.
Season.swift
import Foundation

// The seasons
enum Season  { 
    case Spring 
    case Summer 
    case Autumn 
    case Winter 
    
    // A static Constant, contains all the elements of the Enum.
    static let allValues = [Spring, Summer, Autumn, Winter]  
}
GetAllSeasons.swift
import Foundation 

func test_getAllSeasons()   { 
   for season in Season.allValues  {
       print(season)
   }
}
Results of running the example:
Spring
Summer
Autumn
Winter

3. Enum in switch statement

Like the primitive data types (Int, Float, ..) Enum can be used as a parameter in the switch statement.
Let's look at an example:
SwitchDemo.swift
import Foundation

func test_switchEnum() {
    var day = WeekDay.THURSDAY;
    switch (day) {
    case .MONDAY: 
        print("Working day");
    case .SATURDAY, .SUNDAY :
        print("Holiday");
    default:
        print(day);
    }
}
Edit main.swift:
main.swift
import Foundation

test_switchEnum()
Running the example:
THURSDAY

4. Enum with Raw values

You can define an Enum with raw values, raw values here can be String, character, Int, Number, ... An Enum extends one of the String, Character, Int, ..

For example, you can define an Enum, contains months of the year, this enumeration will contain the raw value from 1 to 12.
RawValueEnum.swift
import Foundation

// Define an Enum is enumeration of months in year.
// It extends from Int
enum Month : Int  { 
    // Assign the value (raw value) for the first element.
    // (If the element is not assigned the value,
    // Default its value equal to the value of the previous element plus 1).
    case January = 1, 
    February, March, April, May, June, 
    July, August, September, October, November, December
    
    // A static Constant contains all the values of Month enum.
    static let allValues = [January,February, March,
                            April, May, June, July, August,
                            September, October, November, December] 
} 
// 
enum Suit:String { 
    case Spades = "♠" 
    case Hearts = "♥" 
    case Diamonds = "♦" 
    case Clubs = "♣"
    
    // A Static Constant contains all the elements of Suit enum.
    static let allValues = [Spades,Hearts,Diamonds,Clubs] 
}
Print out the elements of Month enum, and respective raw value
RawValueEnumTest.swift
import Foundation 

func test_MonthEnum()   { 
    // Print out all elements and raw values of enum.
    print("All element/raw value of Month enum"); 
    for e in Month.allValues  { 
        let rawValue = e.rawValue 
        print("Element \(e), raw value: \(rawValue)"  );
    } 
    print("---------------------");
    
    // Print out all elements and raw values of enum.
    print("All element/raw value of Suit enum");
    
    for e in Suit.allValues  { 
        let rawValue = e.rawValue 
        print("Element \(e), raw value: \(rawValue)"  );
    } 
}
Running the example:
All element/raw value of Month enum
Element January, raw value: 1
Element February, raw value: 2
Element March, raw value: 3
Element April, raw value: 4
Element May, raw value: 5
Element June, raw value: 6
Element July, raw value: 7
Element August, raw value: 8
Element September, raw value: 9
Element October, raw value: 10
Element November, raw value: 11
Element December, raw value: 12
---------------------
All element/raw value of Suite enum
Element Spades, raw value: ♠
Element Hearts, raw value: ♥
Element Diamonds, raw value: ♦
Element Clubs, raw value: ♣

5. Enum with Associated Values

You can create an Enum with element that can contain values associated with it.
For example, you create an Enum contains promotion types.
  • GIFT
  • DISCOUNT
  • MONEY
  • SHIPPING
The problem is that every form of promotion has the values associated with it, such GIFT (gift name & quantity). Or MONEY (amount), ...

Thus each element of Enum has different parameters. Consider the example:
Promotion.swift
import Foundation

// Promotion types
enum Promotion   { 
    // Gift (Name and quantity)
    case GIFT (name: String, quantity: Int)
    
    // Discount (percel: 0 - 100)
    case DISCOUNT(percent: Int)
    
    // Money
    case MONEY(amount : Int)
    
    // Free shipping.
    case SHIPPING 
}
Promotion enum only have 4 elements, you can not add or remove its element, its associated values is determined in running time of the program.
PromotionTest.swift
import Foundation

// Simulate a purchase, and get promotions.
func getRandomPromotion() -> Promotion { 
    // A random value
    var random: UInt32 = arc4random()
    
    // Divided by 4 and returns the remainder (0, 1, 2, 3).
    random = random % 4
    
    switch random  { 
    case 0:
        return Promotion.DISCOUNT(percent: 10)
    case 1:
        return Promotion.GIFT(name: "Doll", quantity: 1)
    case 2:
        return Promotion.MONEY(amount: 100)
    case 3:
        return Promotion.SHIPPING
    default:
        return Promotion.SHIPPING
    } 
} 
func test_Promotion()   {  
    var myProm = getRandomPromotion() 
    print("Get Promotion: \(myProm)")  
    switch myProm {
    case .DISCOUNT(let percent):
        print("Percent is: \(percent)")
    case .GIFT(let name, let quantity ):
        print("Gift name: \(name), quantity: \(quantity)")
    case .MONEY(let amount) :
        print("Amount: \(amount)")
    default:
        print(myProm)
    }
}
Edit main.swift:
main.swift
import Foundation

test_Promotion()
Running the example:
Get Promotion: GIFT("Doll", 1)
Gift name: Doll, quantity: 1

6. Methods in enum

You can define the methods of Enum, see for example:
Currency.swift
import Foundation 

// Currencies.
enum Currency   { 
    case USD
    case YEN
    case VND  
    func description() -> String  { 
        switch self {
        case USD:
            return "America's currency"
        case YEN:
            return "Japan's currency"
        case VND :
            return "Vietnam's currency"
        }
    } 
}