Codementor Events

Learn Swift: Enums and Closures

Published Dec 22, 2016Last updated Jan 18, 2017
Learn Swift: Enums and Closures

Today we will be talking about Enums and Closures in the Swift programming language. We will touch on type-safety, different enum types, as well as a common type of closure, the completion handler. If you're a beginner, this is a Swift tutorial you should pay close attention to.

Enums

Enums or enumerations are a way to group a common type of values together in way that is type-safe. Enumerations purposely declare a finite amount of items which help to make your code and intentions more clear.

Let’s talk about type-safety

One of the most important features of Swift is that it was designed with type-safety in mind. Type-safety means that if you’re using a type in a way that it is not designed, you will not be allowed to proceed. Everyone makes mistakes and programmers are no exception. Type-safety is there to help eliminate those small typing errors which could potentially have profound consequences for your applications.

In our example below, we create two integer constants and assign values to them. We create a third object of type String and attempt to assign it a value from a calculation of the other integers. If you’re confused, that’s okay. It’s not correct and is not the type of operation that you’re going to do on purpose, rather, something like that may happen after a long day of coding.

Swift knows that a String constant isn’t able to hold an Integer, so it throws a fit and errors out.

learn swift

Creating an enum

To create an enumeration, we use the enum keyword and name it something useful. In our case, we created an enum called Vehicles, which lists all of the vehicle types we are working with inside our example app. Each individual item inside the brackets is referred to as an enumeration case.

    enum Vehicles {
        
        case car
        case truck
        case train
        case ship
        case bicycle
        case motorcycle
        
    }

Following Swift language guidelines, we capitalize types and this means we also will want to capitalize the name of our Vehicle enumeration. Individual cases inside the enumeration begin with the case keyword and are written in lowercase.

It is also possible to list all enumeration cases on the same line, such as this:

    enum Vehicles {
    
        case car, truck, train, ship, bicycle, motorcycle
        
    }

Note: Enumeration cases are not implicitly given an integer value. Other languages such as C and Objective-C, assign each enumeration case a default integer value. For example, using the above enum, car would equal 0, truck would be 1 and so on. This is not the case with Swift.

Code completion

An awesome benefit to enums is that you can access them through the code completion feature inside Xcode. With the Vehicles enum declared (like above), try to access the enum by assigning a case to a variable.

Xcode’s friendly, often times unpredictable code completion feature kicks in and lists exactly the options available to us. If you try to assign the myVehicle constant as type Vehicles.moped, Xcode will catch that and not let you proceed. That’s an example of type safety with enums.

learn swift

Setting Raw Values

Often times it’s helpful to store raw values inside an enum. Let’s say that we want to store a number of possible countries in our enumeration and also the demonym used for the people living in each country.

    enum Countries: String {
        
        case UnitedStates = "American"
        case Germany = "German"
        case France = "French"
        case Canada = "Canadian"
        
    }

Declaring our enum as type String allows us to assign a string value to each enumeration case within it.

Closures

A closure is defined as a self-contained block of functionality which can be passed around and used in your code. Closures in the Swift programming language are similar to blocks in C and Objective-C. A big difference, in my opinion, between closures in other languages, is that Swift simplifies the syntax — making them both easier to read and write.

It should be noted that closures in Swift are first-class citizens. This means that they can be passed as a parameter, returned from a function or assigned to a variable. You may not know it but functions are actually a special case of closure in the Swift programming language.

Completion closure

One of the most commonly used examples of a closure in iOS is a function with a completion handler. Completion handlers are useful in mobile app development as they allow you to be notified when a long-running task is complete. Once the completion handler returns, you’re able to refresh the data on the screen or perform another task.

Perhaps you need to download a large file or do some heavy lifting in your database. Your user interface will not be updated after the task is finished unless you use a delegate to listen in or use a completion handler to know when the task is finished.

Let’s say that we need to make a network call to check if an API key is valid. First we create our function called simply validateKeyWithWebService(). Because the function includes a call to a web service, which will not return immediately, we add a completion handler to gracefully handle the request, no matter how long it ends up taking.

Once the web service gets back to us about whether they key is valid, the completionHandler() is called with a simple Boolean; true for success or false for failure.

    func validateKeyWithWebService(key:String, completionHandler:(_ success:Bool) -> Void) {
        
        //In our example, our call to a web server would be here as well
        //as any other long running task that needs to be completed.
        
        //We use the next line to indicate that we are finished with our task.
        completionHandler(true)
    }

In our example, we will be calling a function named validateKeyWithWebService() which includes a closure.

        validateKeyWithWebService(key: "1149-12341-51351-15516", completionHandler:{(success:Bool) -> Void in
           
           //This is called AFTER the completion handler is called,
           //that means if you get to this point, your long running task is finished working.
           
            if success {
                print("Our key is valid")
            }else{
                print("Our key is invalid.")
            }
            
        })

When the networking call is completed, the Bool named success is read and it is at this point where we update the user interface and let the user know whether the operation was successful or not.

It should be noted that there are many different types of closures in the Swift programming language. Completion handlers are just a single example of how closures can be immensely helpful.

Closure syntax

If we break down the syntax of a typical closure, we see that they are enclosed inside curly braces { }. Parameters go inside the parentheses ( )and -> is used to separate the return type. If you’re coming from another programming language, you’re probably used to seeing the caret (^) character inside your blocks although seemed to have missed the jump to Swift.

learn swift

Wrapping up

That’s it for today, we hope you’ve learned a few new things and you get to put them to good use inside your own iOS apps.


Author's Bio

learn swiftRyan Hartman is a senior iOS developer with over 7 years of experience creating awesome apps for iOS and Mac. Located in beautiful Berlin, Germany, he is passionate about helping others learn about programming, UI/UX design, and other technical topics.

Discover and read more posts from Codementor Team
get started
post commentsBe the first to share your opinion
Abdul Hameed
7 years ago

It helped me to understand compilation handler !!
Thanks

Show more replies