Enumerations

An enumeration 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.

Enumerations in Swift are first-class types in their own right. They adopt many features traditionally supported only by classes, such as computed properties.

enum CompassPoint {
    case north
    case south
    case east
    case west
}

enum Planet {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}

var directionToHead = CompassPoint.west
directionToHead = .east

for planet in Planet.allCases {
    print(planet)
}

Enumerations useful in switch statement.

directionToHead = .south
switch directionToHead {
    case .north:
        print("Lots of planets have a north")
        break
    case .south:
        print("Watch out for penguins")
        break
    case .east:
        print("Where the sun rises")
        break
    case .west:
        print("Where the skies are blue")
        break
}
// Prints "Watch out for penguins"

The default keyword allows you to handle other cases in switch statement.

switch directionToHead {
    case .north:
        print("Lots of planets have a north")
        break
    default:
        print("other cases are .south, .east, .west")
        break
}

associative enumerations

You can define Swift enumerations to store associated values of any given type, and the value types can be different for each case of the enumeration if needed. This is similar to variants in other programming languages.

enum FeedViewState {
    case normal([FeedPost] = [])
    case loading
    case refreshing
    case error(FeedViewError)
}

Use let keyword to use associative values in switch statement.

switch state {
case .normal(let newData):
    onNormal(newData)
    break
case .error(let error):
    if data.isEmpty {
         onErrorFirstEmpty(error)
    }
    break
case .loading, .refreshing:
    // ... do something
}

if case

Usually the enumeration is processed in a switch statement. But sometimes you just need to check if the enum is equal to a given value. In this case you can use if case or guard case statement.

// we don't need associative value of normal  
// so we use underscore
if case .normal(_) = currentState , indexPath.row == lastElement {
    presenter.loadData(refresh: false)
}

guard case .a = myEnumVariable else {
    return
}

protocols

Enumerations can conform protocols. Typical example is Error protocol.

enum FeedViewError: Error {
    case internetConnectionIsFailed
    case dataIsEmpty
    case serverError
    case otherError
}

enum YourEnum: YourProtocol {
    case a
    case b
 
    //-------------------------------
    // protocol implementation
}