Welcome to Lesson 2 of Advanced Enum. You will learn how to utilize properties and methods within enums to produce safe and beautiful code. The examples will include UIStoryboard
, Cell Identifier
, and UIColor
.
Let's make it practical
Create an enum called Storyboard
with raw value, String
. It contains a computed property called, identifier
whose type is String
.
enum Storyboard: String {
case profile
case setting
case newsfeed
var identifier: String {
return self.rawValue
}
}
You no longer have to type manually.
let profile = Storyboard.profile
profile.identifier // "profile"
Hypothetically, you may need to create a function with a parameter whose type is Storyboard
.
func describeStoryboard(storyboard: Storyboard) -> String {
switch storyboard {
case .profile:
return "\(storyboard.identifier): Profile picture, followers"
case .setting:
return "\(storyboard.identifier): Logout, invite"
case .newsfeed:
return "\(storyboard.identifier): videos, texts"
}
}
Instead of typing manually, you are able to pick and choose any cases within Storyboard
. Look familar?
describeStoryboard(storyboard: .profile)
You may create a mutating
function that mutates its own case
.
enum MealProcess: String {
case breakfast, lunch , dinner
var description: String {
return self.rawValue
}
mutating func nextMeal() {
print("Time to move on from \(self.description)")
switch self {
case .breakfast:
self = .lunch
print("I had a nice lunch")
case .lunch:
self = .dinner
print("I had a nice dinner")
case .dinner:
self = .breakfast
print("I had a nice breakast")
}
}
}
Important:
self
refers to the initialized enum object with a defined case.
Let us initialize an object with the breakfast
case and call the nextMeal()
function.
var currentMeal = MealProcess.breakfast
currentMeal.nextMeal() // .lunch
currentMeal.nextMeal() // .dinner
The nextMeal
function modifies the case of currentMeal
.
Create an enum called, AppleDevices
. It contains a static
function which returns AppleDevices
based on the name of the parameter used in the function.
enum AppleDevices {
case iWatch, iPhone, iMac, MacPro
static func getAppleDevice(name: String) -> AppleDevices? {
switch name {
case "iWatch":
return .iWatch
case "iPhone":
return .iPhone
case "iMac":
return .iMac
case "MacPro":
return .MacPro
default:
return nil
}
}
}
You may return an initialized enum object by calling getAppleDevice
.
let userProduct = AppleDevices.getAppleDevice(name: "iWatch")
print(userProduct) // AppleDevices.iWatch
Let us refactor using raw value.
enum AppleDevices: String {
case iWatch, iPhone, iMac, MacPro
static func getProduct(name: String) -> AppleDevices? {
return AppleDevices(rawValue: name)
}
static func getAppleDevice(enterName: String) -> AppleDevices? {
switch enterName {
case "iWatch", "iPhone", "iMac", "MacPro":
return getProduct(name: enterName)
default:
return nil
}
}
}
Looks nice and zen.
You may add a custom init method to create an object you wish.
enum AppleDevice: String {
case iWatch, iPhone, iMac, MacPro
init?(name: String) {
if name == "iWatch" {
self = .iWatch
} else {
return nil
}
}
}
AppleDevice(name: "iWatch")
AppleDevice(rawValue: "iWatch")
Another example with number category.
enum IntCategory {
case small
case medium
case big
case weird
init(number: Int) {
switch number {
case 0..<1000 :
self = .small
case 1000..<100000:
self = .medium
case 100000..<1000000:
self = .big
default:
self = .weird
}
}
}
IntCategory(number: 12413423432) // .weird
You may organize a group of HTTP instructions using enums instead of multiple tuples.
//: HTTP Request
enum HttpError: String {
case Code400 = "Bad Request"
case Code401 = "Unauthorized"
case Code402 = "Payment Required"
case Code403 = "Forbidden"
case Code404 = "Page Not Found"
var description: String {
return self.rawValue
}
}
HttpError.Code400.description
Like Storyboard
, you want to limit typing with your fingers. Instead, pick and choose.
enum CellType: String {
case ButtonValueCell = "ButtonValueCell"
case UnitEditCell = "UnitEditCell"
case LabelCell = "LabelCell"
case ResultLabelCell = "ResultLabelCell"
var name: String {
return self.rawValue
}
}
No more typing. It is useful both for your teammates with effective communication.
import UIKit
enum NavigationTheme {
case Placid
case Warning
case Danger
var barTintColor: UIColor {
switch self {
case .Placid: return UIColor.clear
case .Warning: return UIColor.blue
case .Danger: return UIColor.red
}
}
}
You may get barTintColor
based on the enum case.
let colorSituation = NavigationTheme.Placid
colorSituation.barTintColor
Enums also support extension
. Let us add a custom init.
extension NavigationTheme {
init(numberOfTasks: Int) {
switch numberOfTasks {
case 0...3:
self = .Placid
case 4...9:
self = .Warning
default:
self = .Danger
}
}
}
The example above is useful for coloring a to-do list app.
Let us retrieve barTintColor
based on numberOfTasks
.
let currentColor = NavigationTheme(numberOfTasks: 10).barTintColor
7002_stating_mutating_self.playground
You've tasted the power of enums. Again, no more typing. In your head, you should be thinking how to deploy enums to beautify your previous projects. If the iOS engineers have not used enums for any APIs, for instance, UIColor
, we, developers, have to memorize and type all day while checking the documentation unlimited times. Use it for your advantage as well.
In the following lesson, you will learn how to add multiple enums within a single enum.
Note: Learn Swift with Bob is available on Udemy. If you wish to receive a discount link, you may sign up here.