How to Use enum and Enumerations in Swift

Often code needs some way to describe a discrete set of cases. You might need values for breakfast lunch and dinner for example. How we configure a view might be set by one of a few choices. There are many types of UIButtons we can use such as system, custom, and detail disclosure. We would declare them like this:

let systemButton = UIButton(type:UIButtonType.System)
let customButton = UIButton(type:.Custom)
let detailDisclosureButton = UIButton(type:.DetailDisclosure)

After the type: parameter we have an enumeration, often called an enum which is the declaration keyword for an enumeration. Enumerations are often misunderstood, and often give powerful ways to control and document code easily. In this lesson, we’ll begin to explore the basic uses for enumeration.

Using IBM’s Swift Sandbox

We won’t write a full app for this lesson. Instead we’ll use a handy tool for exploring the Swift language anywhere there is an internet connection and web browser. In December 2015, Apple released the open source Swift version (Swift 2.2). It does not include the API’s of UIKit, but does have all the Foundation framework. IBM in partnership with Apple launched a website-based playground (which they confusingly call a sandbox) for testing code. I’ll use the IBM Sandbox for this lesson, which I find faster than Xcode’s playground, and you can use it on your iPad or even PC since you don’t need Xcode, just a Web browser. You can certainly use Xcode’s playground if you want.

Open your favorite web browser and navigate to http://swiftlang.ng.bluemix.net/#/repl. You’ll get a website looking like a playground:

2016-01-20_05-28-52.png

Depending on your tastes you can change the skin from dark to light. Click the settings gear on the sandbox, then select the Light Theme.

2016-01-20_05-29-05.png

You’ll get a light color scheme.

2016-01-20_05-29-24.png

You’ll see a snippet of code in the left side code window

//  TODO: Write some awesome Swift code, or import libraries like "Foundation",
//  "Dispatch", or"Glibc"

print("Hello world!")

At the lower center, you’ll find the Run button. Click that button to make your code compile and run. We get the classic Hello World message. If you have syntax errors, they show in the Results side of the page. Remove the quote mark after the exclamation mark from the current code and run again. You get several errors starting with:

/swift-execution/code-tmp.swift:4:7: error: unterminated string literal

Fix the error and run again. The errors are replaced by the Hello World output

Some Code to Fix

To explain enums, let’s make some code that should use it, but doesn’t. Since I’m writing this in January, a lot of people are obsessed with weight loss now. Let’s make a calorie counter to help them out. Delete the source code in the sandbox, and add this code in its place:

import Foundation
var  caloriesTotal = [0,0,0,0]

We made an 4-element array to keep totals for calories for each meal. The first position of this array is breakfast, then lunch, dinner and snack. Add this function to the code:

func addCaloriesForMeal(meal:Int,calorie:Int){
	caloriesTotal[meal] +=  calorie
	print ( "Calories for meal \(meal) is \(caloriesTotal[meal])")
	if meal == 3 {
		print("Try not to snack")
	}
	if (meal == 0) && (caloriesTotal[meal] > 100){
		print("Breakfast is the most important meal of the day. Eat more breakfast.")
	}
}

The code adds calories, gives us feedback to the current calorie count for that meal, and a few comments about our current diet. Without comments, this would be difficult code to understand, and even code for. I have to remember that 0 is breakfast and 3 is snacks. Someone else reading this code would have an even more difficult time. Add the following to call the function:

addCaloriesForMeal(0,calorie:50)
addCaloriesForMeal(1,calorie:280)
addCaloriesForMeal(2,calorie:650)
addCaloriesForMeal(3,calorie:1150)

Run the code and it works.


Calories for meal 0 is 50
Breakfast is the most important meal of the day. Eat more breakfast.
Calories for meal 1 is 280
Calories for meal 2 is 650
Calories for meal 3 is 1150
Try not to snack

The code works. It’s just very difficult to work with

Using Enum

What if we could change the values of 0,1,2,3 with words? We could do this with constants like this:

let breakfast = 0
let lunch = 0
let dinner = 0
let snacks = 0

Even better, we can define a special type that has these constants as the only value of the type. We could use that type anywhere within the scope. This is an enumeration. Add the following code above the var in your current code.

enum Meal:Int{
	case Breakfast = 0
	case Lunch = 1
	case Dinner = 2
	case Snack = 3
}

The first line declares an enumeration type called Meal. We declare Meal to be representing an integer value. The next lines contain the values we are representing. We can now use the enumeration as a constant.To make clear these are not variables, values in an enum have their first letter capitalized. In Swift, you’ll find two ways of using this constant. If there is no context as to type, you will see Meal.Breakfast. If there is a context, such as in a declared parameter or comparison to a value of the same enumeration type, you can write .Breakfast .

Change the declaration for our function to this:

func addCaloriesForMeal(meal:Meal,calorie:Int){

We changed the type for the meal to our enumeration. For most cases this will be all you need to do.

We can now change our Boolean statements to be better documented in the code. Change the first if to this:

 if meal == .Snack {

This is much easier to read than before

The rawValue Property

There is one wrinkle to enums. Unlike a constant or variable, the value of an enum cannot directly assign its value to something else. Our current array index

caloriesTotal[meal] +=  calorie

Would cause an error:

/swift-execution/code-tmp.swift:11:15: error: cannot subscript a value of type '[Int]' with an index of type 'Meal'

Meal is a different type, and Swift requires an Int here. We have a property of enums rawValue. After our function declaration add this line:

let mealIndex = meal.rawValue  //get the raw value of the enumeration

Now change the two lines under it to this:

caloriesTotal[mealIndex] +=  calorie
print ("Calories for meal \(mealIndex) is \(caloriesTotal[mealIndex])")

We have one more line to change in our function. Change the breakfast if statement

if (meal == .Breakfast) && (caloriesTotal[mealIndex] < 100){

Calling the function is a lot easier now. Replace the function calls with the following:

addCaloriesForMeal(.Breakfast,calorie:50)
addCaloriesForMeal(.Dinner,calorie:650)
addCaloriesForMeal(.Snack,calorie:1150)

Now run the code. We get similar results, but our code is a lot easier to read

Using Switch…Case with Enumeration

We’ve already evaluated situations with if statements. Often we will have to do something different for every case in an enumeration. This is where the switch...case decision structure comes in handy. In our code, it’s more user friendly to display breakfast, lunch, dinner, or snack instead of a meal number. Add this code just below the caloriesTotal addition:

//Add a switch statement for a meal string
	var mealString = ""
	switch meal{
	   case .Breakfast:
	    mealString = "breakfast&"
	   case .Lunch:
	    mealString = "lunch"
	   case .Dinner:
	    mealString = "dinner"
	   case .Snack:
	    mealString = "snack"
	}

We first make a new variable for our string. Then we use the switch stating we are looking at options for our meal variable. Within the brackets, we put case and one of our enumeration values. Under that case is code which assigns the value of the strong. Unlike an if...else clause, case does not need a block for these statements. It assumes your next case is the end of your block. However, you must be exhaustive. All values must be listed. If you do not list every value, you must include a default case.

Now that we have a string to use, change the print to this:

print ( "Calories for " + mealString + " is \(caloriesTotal[mealIndex])")

Run your code. You will get a different output:


Calories for breakfast is 50
Breakfast is the most important meal of the day. Eat more breakfast.
Calories for dinner is 650
Calories for snack is 1150
Try not to snack

Methods in Enumerations

There’s a problem with this switch statement. It is not very adaptable. For any use of my enumeration, I might want to get that string. Enumerations, like classes, can have methods. Under case Snack = 3 in the enum add this:

func mealName() -> String{

	return mealString
}

Cut and paste the mealString declaration and the switch statement between the func declaration and the return. In the switch, change mealString to self. Your code should look like this:

func mealName() -> String{
	var mealString = ""
	switch self{
    		case .Breakfast:
			mealString = "breakfast"
		case .Lunch:
			mealString ="lunch"
		case .Dinner:
            mealString = "dinner"
        	case .Snack:
            	mealString = "snack"
    		}
    		return mealString
}

Change the print to this:

print ( "Calories for " + meal.mealName() +" is \(caloriesTotal[mealIndex])")

We called the function mealName which returns our string. Run and we get the same results.

Default Values for Int Enums

Change the enum cases to this, then run again:

enum Meal:Int{
	case Breakfast = 0
	case Lunch
	case Dinner
	case Snack

You get the same results. An enum for an Int assumes that each value will increment by one, and you have only assigned the starting value of 0. Now try this:

enum Meal:Int{
	case Breakfast
	case Lunch
	case Dinner
	case Snack

When you run this, the code still works. Only for a type of Int, Swift’s enums assume a value of 0 and will increment by 1. This of course begs the question: Can you use other types, or no types at all?

Using Other Types

Open a new sandbox in your web browser. Remove the base code and add this:

import Foundation
// Use of other types
//  any Int Float, Double, or String Works here.
enum Meals:String{
    case Breakfast = "breakfast"
    case Lunch = "lunch"
    case Dinner = "dinner"
    case Snack = "snack"
}
print(Meals.Breakfast.rawValue)

Run this and you will get breakfast. We’ve so far used integer values for the enum. We can use it to store strings like we did here. Change the type declaration to the appropriate type.

enum Meals:String

You can use any basic type for an enum raw value including Int, Float, Double, or String. You cannot use a complex values such as an array, class or another enum.

The Bare-Bones enum

Often we don’t need a value constant for our enumeration. We need a discrete set of values only. This basic enum does that:

Meals{
    case Breakfast
    case Lunch
    case Dinner
    case Snack
}
print (Meals.Breakfast)

Try this code in the sandbox. You will once again get Breakfast in the output.There is a very important caution using this. An enum like this has no rawValue. Its only value is one of its four cases. Breakfast is a value, but it is not a String. You’ve created a type that only has the four values.

If you want to do this in a shorter version you can do this:

 Meals{
    case Breakfast,Lunch,Dinner,Snack
}
print (Meals.Breakfast)

The short version works for Int enums with default values

enum Meals:Int{
    case Breakfast,Lunch,Dinner, Snack
}
print(Meals.Lunch)
print(Meals.Lunch.rawValue)

Associative Enumerations

So far, enumerations have been used as a constant. There is one more case that can have assigned values. Called Associative Enumerations they associate any value with a case of a enumerated value. Each case has its own independent type, and must be declared separately as a tuple. For example, let’s associate a calorie count and the food eaten with each meal.

We’ll use a class Food for breakfast. So we don’t know what snack we had use an integer only for .Snack

enum Meals{
 case Breakfast(Food)
 case Lunch(Int,String)
 case Dinner(Int,String)
 case Snack(Int)
 }

Getting a value from this is not as easy as rawValue. You have to extract it in a switch statement. It may be in your code somewhere, or as I did here, add it to the enumeration.

 enum Meals{
    case Breakfast(Food)
    case Lunch(Int,String)
    case Dinner(Int,String)
    case Snack(Int)

    func print() -> String{ //return a string describing the meal
        switch self{
        case let Breakfast(food):
            return "Breakfast: " + food.foodName + " \(food.calories) calories"
        case let Lunch(calories, foodName):
            return "Lunch: " + foodName + " \(food.calories) calories"
        case Dinner(calories, foodName):
            return ("Dinner: " + foodName + " calories: \(calories) ")
        case let Snack(calories):
            return ("A tasty snack of  \(calories) calories")
        }

    }
}

Define a class Food to get this code to work:

class Food{
    var calories:Int = 0
    var foodName:String = ""
    init (calories:Int,foodName:String){
        self.calories = calories
        self.foodName = foodName
    }
}

We defined two properties, calories and foodName in our class. We also added an initializer to assign these values directly to a new instance. If you haven’t worked with initializers, I suggest you take a look at my tutorial on classes for more information on this.

After the enum, let test it with this:

var myMeal = Meals.Breakfast(Food(calories:05,foodName:"Grande Brass Pig"))
print (myMeal.print())
myMeal = .Lunch(380,"Grilled Chicken Sandwich")
print (myMeal.print())
myMeal = .Dinner(1130,"Shwarma Fest Platter")
print (myMeal.print())
myMeal = .Snack(280)
print (myMeal.print())

Run the code. You should get this output


Breakfast: Grande Brass Pig 5 calories
Lunch: Grilled Chicken Sandwich 380 calories
Dinner: Shwarma Fest Platter calories: 1130
A tasty snack of 280 calories

Using enums in Real Life

I rarely use associative enums. Most of the things you can do with them might be better done with classes. If I was writing a real calorie counter app like My Fitness Pal, I’d declare a class with an enum as a property like this:

//The enumeration Declared outside of the class it defaults to global for the target.
enum Meals:Int{
    case Breakfast
    case Lunch
    case Dinner
    case Snack 

}
class FoodEntry{
    var foodName:String
    var calories:Int
    var meal:Meals
    init(meal:Meals,foodName:String,calories:Int){
	     self.meal = meal
	     self.foodName = foodName
	     self.calories = calories
    }
}

Make a new sandbox, and add the code above. I could include the enum in the class definition. I generally don’t if I’m defining a class for a model. It’s likely that I will be using boolean expressions at some point to compare things. This

if food.meal == .Breakfast 

is easier to write than

if food.meal == food.Meals.Breakfast

As I did earlier, I did use a constant Int on my enumeration to use it in arrays. This FoodEntry class could also be used in an array for my daily food list in a class for daily food entries:

class DailyFoodIntake{
	var foodList:[FoodEntry] = []
	var totalCalories = 0
	let zeroMealCalories = [0,0,0,0]
	var mealCalories:[Int] = [0,0,0,0]

This class also keeps track of total calories for each meal and for the day. I can set up a few functions like this to use these properties:

func computeCalories(){
	    //recompute daily and meal calorie intake
	    totalCalories = 0
	    mealCalories = zeroMealCalories
	    for food in foodList{
	        totalCalories += food.calories
	        mealCalories[food.meal.rawValue] += food.calories
	    }
	    print("Total Calories today: \(totalCalories)")
	    print("\tBreakfast: \(mealCalories[Meals.Breakfast.rawValue]) calories")
	    print("\tLunch: \(mealCalories[Meals.Lunch.rawValue]) calories")
	    print("\tDinner: \(mealCalories[Meals.Dinner.rawValue]) calories")
	    print("\tSnack: \(mealCalories[Meals.Snack.rawValue]) calories")
	}
	func addFoodForMeal(meal:Meals,foodName:String,calories:Int){
	    let food = FoodEntry(meal:meal,foodName:foodName,calories:calories)
	    foodList += [food]
	    computeCalories()
	}

The addFoodForMeal method adds a food to the array and then calls the computeCalories to recompute the totals for the day. This clears the totals first then adds everything up in a loop. For the meals, we use the rawValue to get an index for the array to total the current value:

mealCalories[food.meal.rawValue] += food.calories

After computing, the totals get printed on the console, with a tab stop indentation. Again, we use the rawValue to get an index.

print("\tBreakfast: \(mealCalories[Meals.Breakfast.rawValue]) calories")
print("\tLunch: \(mealCalories[Meals.Lunch.rawValue]) calories")
print("\tDinner: \(mealCalories[Meals.Dinner.rawValue]) calories")
print("\tSnack: \(mealCalories[Meals.Snack.rawValue]) calories")

Add the following test data

let today = DailyFoodIntake()
today.addFoodForMeal(.Breakfast,foodName:"coffee",calories:5)
today.addFoodForMeal(.Breakfast,foodName:"oatmeal",calories:170)
today.addFoodForMeal(.Lunch,foodName:"turkey dogs",calories: 90)
today.addFoodForMeal(.Dinner,foodName:"Turkey Burger",calories: 340)
today.addFoodForMeal(.Dinner,foodName:"Sweet Potato Fries",calories: 270)
today.addFoodForMeal(.Snack,foodName:"Candy Bar",calories: 280)
today.addFoodForMeal(.Snack,foodName:"Ice Cream mini bar",calories: 180)

Run the code. You’ll get output starting like this:


Total Calories today: 5
Breakfast: 5 calories
Lunch: 0 calories
Dinner: 0 calories
Snack: 0 calories
Total Calories today: 175
Breakfast: 175 calories
Lunch: 0 calories
Dinner: 0 calories
Snack: 0 calories
Total Calories today: 265
Breakfast: 175 calories
Lunch: 90 calories
Dinner: 0 calories
Snack: 0 calories

This is a little too much for our output. Notice we had to write out four print statements. Since you can’t iterate an enum this was necessary. Let’s do a modification to our code to better use our enum. Start by adding a function for a string in the enum

func mealsString()-> String{
        switch self{
            case Breakfast:
                return "breakfast"
            case Lunch:
                return "lunch"
            case Dinner:
                return "dinner"
            case Snack:
                return "snack"
        }

    }

Next, remove the print statements from computeCalories. Change the addFoodForMeal to this

func addFoodForMeal(meal:Meals,foodName:String,calories:Int){
	    let food = FoodEntry(meal:meal,foodName:foodName,calories:calories)
	    foodList += [food]
	    computeCalories()
	    print("Total Calories today: \(totalCalories)")
	    print("\tAdded  \(calories) calories for total of \(mealCalories[meal.rawValue]) \(meal.mealsString()) calories")
	}

In this function, unlike computeCalories, we have a value meal that tells us which meal this is. Instead of printing all the meals, we only print the meal that changed. We use the mealsString function to have a string value for our enum, since we already have an integer one. Run this and you get a different output


Total Calories today: 5
Added 5 calories for total of 5 breakfast calories
Total Calories today: 175
Added 170 calories for total of 175 breakfast calories
Total Calories today: 265
Added 90 calories for total of 90 lunch calories
Total Calories today: 605
Added 340 calories for total of 340 dinner calories
Total Calories today: 875
Added 270 calories for total of 610 dinner calories
Total Calories today: 1155
Added 280 calories for total of 280 snack calories
Total Calories today: 1335
Added 180 calories for total of 460 snack calories

 

Enumeration is the way in swift to deal with options in a function or application easily. In the above example, we used meals, but any small set of constant options works well in one. If you have a changing list or a large one, you might use a different data type like an array or dictionary. As you explore the UIKit API’s you’ll find many uses for enums. You’ll undoubtedly find many more.

The Whole Code

You’ll find the code below for this lesson. Uncomment each part you want to use. You’ll also find it available in the IBM Swift Sandbox here

import Foundation
//Uncomment code to run each iteration.
// find this code at the IBM Swift sandbox at
// swiftlang.ng.bluemix.net/#/repl/057089281afdef410b81365650399f0935617405bf64e7e54806b010e9af6c09
import Foundation
//Uncomment code to run each iteration.
/*
// Iteration one -- Unreadable code
var  caloriesTotal = [0,0,0,0] //Breakfast,Lunch,Dinner,Snack calories
func addCaloriesForMeal(meal:Int,calorie:Int){
//using the rawValue property of enum to get the integer assigned to the enum
	caloriesTotal[meal] = calorie
// using an enum in a boolean expression -- yell at us if snacking
	if meal == 3 {
		print("Try not to snack")
	}
}

func printCaloriesForMeal(meal:Int){
//using the rawValue property of enum to get the integer assigned to the enum
	print ( "Calories for meal \(meal) is \(caloriesTotal[meal])")
// using an enum in a comparison -- Breakfast less than 100 calories
	if (meal == 0) &&  (caloriesTotal[meal] < 100){
		print("Breakfast is the most important meal of the day. Eat more breakfast.")
	}
}

addCaloriesForMeal(0,calorie:50)
addCaloriesForMeal(2,calorie:650)
addCaloriesForMeal(3,calorie:1150)

printCaloriesForMeal(0)
printCaloriesForMeal(3)
*/

/*
// Iteration two add an enumeration and use value and rawValue
enum Meal:Int{
	case Breakfast = 0
	case Lunch = 1
	case Dinner = 2
	case Snack = 3
}

var  caloriesTotal = [0,0,0,0]
func addCaloriesForMeal(meal:Meal,calorie:Int){
//using the rawValue property of enum to get the integer assigned to the enum
	caloriesTotal[meal.rawValue] = calorie
// using an enum in a boolean expression -- yell at us if snacking
	if meal == .Snack {
		print("Try not to snack")
	}
}

func printCaloriesForMeal(meal:Meal){
//using the rawValue property of enum to get the integer assigned to the enum
	print ( "Calories for meal \(meal.rawValue) is \(caloriesTotal[meal.rawValue])")
// using an enum in a comparison -- Breakfast less than 100 calories
	if (meal == .Breakfast) &&  (caloriesTotal[meal.rawValue] < 100){
		print("Breakfast is the most important meal of the day. Eat more breakfast.")
	}
}

addCaloriesForMeal(.Breakfast,calorie:50)
addCaloriesForMeal(.Dinner,calorie:650)
addCaloriesForMeal(.Snack,calorie:1150)

printCaloriesForMeal(.Breakfast)
printCaloriesForMeal(.Snack)
*/

/*
// Iteration three add a switch to make a descriptive string
// enum only has an intial value, values increment from there
enum Meal:Int{
	case Breakfast = 0
	case Lunch
	case Dinner
	case Snack
}

var  caloriesTotal = [0,0,0,0]
func addCaloriesForMeal(meal:Meal,calorie:Int){
	caloriesTotal[meal.rawValue] = calorie
	if meal == .Snack {
		print("Try not to snack")
	}
}

func printCaloriesForMeal(meal:Meal){
//Adding a Switch Statement here to create a string from the enum
    var mealString = ""
    switch meal{
        case .Breakfast:
            mealString = "breakfast"
        case .Lunch:
            mealString = "lunch"
        case .Dinner:
            mealString = "Dinner"
        case .Snack:
            mealString = "Snack"
    }

	print ( "Calories for " + mealString + " is \(caloriesTotal[meal.rawValue])")
	if (meal == .Breakfast) &&  (caloriesTotal[meal.rawValue] < 100){
 		print("Breakfast is the most important meal of the day. Eat more breakfast.")
 	}
 }
 addCaloriesForMeal(.Breakfast,calorie:50)
 addCaloriesForMeal(.Dinner,calorie:650)
 addCaloriesForMeal(.Snack,calorie:1150)
 printCaloriesForMeal(.Breakfast)
 printCaloriesForMeal(.Snack)
*/
/*
 // Iteration four   -- using a function for the case in the enum
 // default is 0 for the first enum, so we don't assign anything
 // I tend to be paranoid and do like iteration 2 if I need raw values.
  enum Meal:Int{
 	case Breakfast = 0
 	case Lunch
 	case Dinner
 	case Snack
 // A function within the enum.
 // Uses self to get the enumeration's value
  func mealName() -> String{
    var mealString = ""
	switch self{
        case .Breakfast:
            mealString = "breakfast"
        case .Lunch:
            mealString = "lunch"
        case .Dinner:
            mealString = "Dinner"
        case .Snack:
            mealString = "snack"
    }
    return mealString
	}
}

var  caloriesTotal = [0,0,0,0]
func addCaloriesForMeal(meal:Meal,calorie:Int){
	caloriesTotal[meal.rawValue] = calorie
	if meal == .Snack {
		print("Try not to snack")
	}
}

func printCaloriesForMeal(meal:Meal){
    /*var mealString = ""
    switch meal{
        case .Breakfast:
            mealString = "breakfast"
        case .Lunch:
            mealString = "lunch"
        case .Dinner:
            mealString = "Dinner"
        case .Snack:
            mealString = "Snack"
    }*/

	print ( "Calories for " + meal.mealName() + " is \(caloriesTotal[meal.rawValue])")
	if (meal == .Breakfast) && (caloriesTotal[meal.rawValue]< 100){
 		print("Breakfast is the most important meal of the day. Eat more breakfast.")
 	}
 }
 addCaloriesForMeal(.Breakfast,calorie:50)
 addCaloriesForMeal(.Dinner,calorie:650)
 addCaloriesForMeal(.Snack,calorie:1150)
 printCaloriesForMeal(.Breakfast)
 printCaloriesForMeal(.Snack)
 */
 /*
 // Use of other types
  //  any Int Float, Double, or String Works here.
  enum Meals:String{
     case Breakfast = "breakfast"
     case Lunch = "lunch"
     case Dinner = "dinner"
     case Snack = "snack"
 }
 print(Meals.Breakfast.rawValue)
 */
 /*
 // Basic enum to make a discrete set of values
 enum Meals{
    case Breakfast
    case Lunch
    case Dinner
    case Snack
}
print (Meals.Breakfast)
*/
/*
 //If you want to do this in a shorter version you can do this:
enum Meals{
   case Breakfast,Lunch,Dinner,Snack
}
print (Meals.Breakfast)
*/
/*
 //The short version works for Int enums with default values
enum Meals:Int{
   case Breakfast,Lunch,Dinner,Snack
}
*/
/*
// Associative enums
  class Food{
     var calories:Int = 0
     var foodName:String = ""
     init (calories:Int,foodName:String){
         self.calories = calories
         self.foodName = foodName
     }
 }
 enum Meals{
     case Breakfast(Food)
     case Lunch(Int,String)
     case Dinner(Int,String)
     case Snack(Int)
     func print() -> String{
        switch self{
        case let Breakfast(food):
            return "Breakfast: " + food.foodName + " \(food.calories) calories"
        case let Lunch(calories, foodName ):
            return "Lunch: " + foodName + " \(calories) calories"
        case let Dinner(calories, foodName):
            return ("Dinner: " + foodName + " calories: \(calories) ")
        case let Snack(calories):
            return ("A tasty snack of  \(calories) calories")
        }

    }
}

var myMeal = Meals.Breakfast(Food(calories:05,foodName:"Grande Brass Pig"))
print (myMeal.print())
myMeal = .Lunch(380,"Grilled Chicken Sandwich")
print (myMeal.print())
myMeal = .Dinner(1130,"Shwarma Fest Platter")
print (myMeal.print())
myMeal = .Snack(280)
print (myMeal.print())
*/
/* 

// a realistic use of enumeration in a calorie counter.
enum Meals:Int{
    case Breakfast
    case Lunch
    case Dinner
    case Snack 

}
class FoodEntry{
    var foodName:String
    var calories:Int
    var meal:Meals
    init(meal:Meals,foodName:String,calories:Int){
	     self.meal = meal
	     self.foodName = foodName
	     self.calories = calories
    }
}

class DailyFoodIntake{
	var foodList:[FoodEntry] = []
	var totalCalories = 0
	let zeroMealCalories = [0,0,0,0]
	var mealCalories:[Int] = [0,0,0,0]

	func computeCalories(){
	    //recompute daily and meal calorie intake
	    totalCalories = 0
	    mealCalories = zeroMealCalories
	    for food in foodList{
	        totalCalories += food.calories
	        mealCalories[food.meal.rawValue] += food.calories
	    }
	    print("Total Calories today: \(totalCalories)")
	    print("\tBreakfast: \(mealCalories[Meals.Breakfast.rawValue]) calories")
	    print("\tLunch: \(mealCalories[Meals.Lunch.rawValue]) calories")
	    print("\tDinner: \(mealCalories[Meals.Dinner.rawValue]) calories")
	    print("\tSnack: \(mealCalories[Meals.Snack.rawValue]) calories")
	}
	func addFoodForMeal(meal:Meals,foodName:String,calories:Int){
	    let food = FoodEntry(meal:meal,foodName:foodName,calories:calories)
	    foodList += [food]
	    computeCalories()
	}
}

let today = DailyFoodIntake()
today.addFoodForMeal(.Breakfast,foodName:"coffee",calories:5)
today.addFoodForMeal(.Breakfast,foodName:"oatmeal",calories:170)
today.addFoodForMeal(.Lunch,foodName:"turkey dogs",calories: 90)
today.addFoodForMeal(.Dinner,foodName:"Turkey Burger",calories: 340)
today.addFoodForMeal(.Dinner,foodName:"Sweet Potato Fries",calories: 270)
today.addFoodForMeal(.Snack,foodName:"Candy Bar",calories: 280)
today.addFoodForMeal(.Snack,foodName:"Ice Cream mini bar",calories: 180)
*/

/*
// changes to the output to summarize the meal eaten and daily totals
enum Meals:Int{
    case Breakfast
    case Lunch
    case Dinner
    case Snack 

    func mealsString()-> String{
        switch self{
            case Breakfast:
                return "breakfast"
            case Lunch:
                return "lunch"
            case Dinner:
                return "dinner"
            case Snack:
                return "snack"
        }

    }
}
class FoodEntry{
    var foodName:String
    var calories:Int
    var meal:Meals
    init(meal:Meals,foodName:String,calories:Int){
	     self.meal = meal
	     self.foodName = foodName
	     self.calories = calories
    }
}

class DailyFoodIntake{
	var foodList:[FoodEntry] = []
	var totalCalories = 0
	let zeroMealCalories = [0,0,0,0]
	var mealCalories:[Int] = [0,0,0,0]

	func computeCalories(){
	    //recompute daily and meal calorie intake
	    totalCalories = 0
	    mealCalories = zeroMealCalories
	    for food in foodList{
	        totalCalories += food.calories
	        mealCalories[food.meal.rawValue] += food.calories
	    }
	}

	func addFoodForMeal(meal:Meals,foodName:String,calories:Int){
	    let food = FoodEntry(meal:meal,foodName:foodName,calories:calories)
	    foodList += [food]
	    computeCalories()
	    print("Total Calories today: \(totalCalories)")
	    print("\tAdded  \(calories) calories for total of \(mealCalories[meal.rawValue]) \(meal.mealsString()) calories")

	}
}

let today = DailyFoodIntake()
today.addFoodForMeal(.Breakfast,foodName:"coffee",calories:5)
today.addFoodForMeal(.Breakfast,foodName:"oatmeal",calories:170)
today.addFoodForMeal(.Lunch,foodName:"turkey dogs",calories: 90)
today.addFoodForMeal(.Dinner,foodName:"Turkey Burger",calories: 340)
today.addFoodForMeal(.Dinner,foodName:"Sweet Potato Fries",calories: 270)
today.addFoodForMeal(.Snack,foodName:"Candy Bar",calories: 280)
today.addFoodForMeal(.Snack,foodName:"Ice Cream mini bar",calories: 180)

*/

One Reply to “How to Use enum and Enumerations in Swift”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s