iOS From Scratch With Swift: Swift in a Nutshell

Apple introduced the Swift programming language during its annual developer conference in 2014, much to he surprise of the developer community. The company is serious about Swift, it isn't an experiment. The goal for Swift is to power the next generation of applications for Apple's platforms.

Prerequisites

Programming

It isn't possible to cover the basics of programming and learn Swift in one or two articles. I am therefore assuming that you already have some programming experience. Ruby, PHP, or JavaScript are good starting points for learning Swift. If you come from a web development background, then you shouldn't have problems learning the basics of Swift by reading the next two articles.

Swift

In the next two articles, I show you the power of playgrounds, a feature introduced in Xcode 6. We also cover the basics of the Swift programming language, such as variables, constants, and data types, including sets, arrays, and dictionaries.

You also learn the basics of classes and structures. In the next article, we zoom in on closures, functions, protocols, and access control. That should give you enough understanding of the language to complete the rest of this series.

Objective-C

Strictly speaking, C and Objective-C aren't required if you are interested in developing for the iOS platform. That said, most of the frameworks we will use to develop iOS applications are written in C and Objective-C. This means that I'll occasionally talk about C and Objective-C. Don't worry, though, I'll make sure you understand whatever is essential to keep you on track to reach your goal, become an iOS developer.

Xcode and Swift

Throughout this series, I will be using Xcode 7.1 and Swift 2.1. If you are using an older version of Xcode, then keep in mind that you won't be working with Swift 2.1. Swift continues to change at a rapid pace and the syntax evolves with every iteration of the language. I therefore recommend using Xcode 7.1, which includes Swift 2.1.

1. Playgrounds

In 2014, Apple introduced playgrounds as part of Xcode 6. Playgrounds are great for learning the Swift programming language. With playgrounds, you can focus on the code you're writing instead of messing with project settings, files, and folders.

Let's create a playground to start learning the basics of Swift. Fire up Xcode 7.1 and choose New > Playground... from Xcode's File menu. Playgrounds support OS X, iOS, and tvOS. Set Platform to iOS and name the playground Swift in a Nutshell.

Create a Playground

Tell Xcode where you want to save the playground and click Create. At first glance, a playground appears to be a simple file with a .playground extension, but it's actually a folder with a handful of files. Fortunately, that's not something we need to worry about. A playground is much easier to deal with than an Xcode project with dozens of files and folders.

Playground User Interface

The user interface of a playground is clean and simple. You can see the code editor on the left and the output on the right. Xcode has already populated the playground with three lines of code. The first line should look familiar if you've read the previous tutorial.

The line starts with two forward slashes, //, indicating that this line is a comment and ignored by the compiler. Comments that span multiple lines start with /* and end with */.

Xcode also added an import statement for the UIKit framework. UIKit is the most important framework for iOS development. It defines the building blocks iOS applications are built with. In Swift, importing a framework is as simple as using the import keyword followed by the name of the framework, UIKit.

The last line may remind some of you of JavaScript. We use the var keyword to declare a variable, str, and assign a value to it, "Hello, playground". This example immediately shows a key feature of Swift, type inference.

The above example is a bit misleading. You may think that Swift is a weakly typed language, but nothing could be further from the truth. The str variable is of type String. Swift is smart enough to infer the type of str by looking at the value we assign to it.

The following example is equivalent. In this example, we explicitly specify the type of the str variable. The colon following the name of the variable could be read as is of type.

2. Variables and Constants

Swift also defines the let keyword. This keyword is used to declare a constant. The Swift programming language encourages the use of constants whenever possible. If the value of a variable doesn't change during its lifetime, it should be a constant. As the name implies, once a constant is given a value, it cannot be changed. This is illustrated in the following example.

The value of a constant cannot be changed

In the above example, we declare a constant message and assign it a value. A few lines down, we assign a new value to the message constant. Because we attempt to change the value of message, the compiler throws an error. Fortunately, the compiler makes a suggestion to fix the issue, turning the message constant into a variable.

3. Data Types

Swift defines a wide range of data types, but let's take a look at some of the most common data types you'll come across.

Booleans

Let's start with a simple type, Bool. Booleans in Swift are just as simple and easy to use as they are in other languages. The following example is probably as simple as it gets in Swift.

Numbers

Numbers are represented by Int, UInt, Float, or Double. There are other data types for storing number values, but these are the most common ones. These data types are similar to the ones you find in other programming languages.

Because Swift is a strongly typed language, you need to deal with type conversions from time to time. For example, it's not possible to multiply an Int and a Float. Take a look at the following example to better understand the problem.

Type Conversion

At first, this may seem like a major shortcoming of the Swift language. The truth is that this behavior is inherent to most strongly typed languages. Fortunately, the solution is simple as you can see below.

Converting a Number

Even though it may seem as if we are casting a to a Float, that's not what's happening. We are creating or initializing a Float using the value stored in a.

There are two ways to create a variable or constant, literal syntax and initializer syntax. The constants a and b were created using literal syntax. The str variable we discussed earlier is another example of literal syntax.

To create a Float from the value stored in a, we use initializer syntax. We create the Float by using the type's name, Float, followed by two parentheses, passing in a as a parameter.

Strings

We've already encountered some strings in this tutorial. A string is nothing more than a sequence of characters. In fact, it's possible to access the collection of characters as shown in the example below.

In the above example, we use a string literal. The next example illustrates how to use the initializer of the String type. The syntax is identical to what we saw in one of the previous examples about numbers and type conversion.

Collections

The Swift standard library defines three common collection types, Array, Dictionary, and Set. These collection types require little explanation if you're familiar with Objective-C or any other programming language. In some languages, dictionaries are known as hashes and arrays are known as lists. The idea, however, is the same.

The array and dictionary are initialized using literal syntax. Because the Set type doesn't have a literal syntax, we use the initializer syntax to create the mySet constant.

I already mentioned that Swift is a strongly typed language and this also has consequences for collection types. The following example illustrates this. We start by creating a variable arr1 of type [Int]. This means that arr1 can only contain values of type Int.

Collection Types

The second and third statement confirm this. Appending an integer works fine, but appending a string results in a compiler error. The compiler attempts to convert "Two" to an Int, but is unable to do so. The result is an error.

The following example will make things even more confusing. Why isn't the compiler complaining about the array containing values of different types? The reason may surprise you. The arr2 constant is of type [AnyObject].

Any and AnyObject

The Swift standard library defines two special types, Any and AnyObject. The Any type can represent any type while the AnyObject type can represent any class or structure. If you're confused, then that's perfectly normal. Swift was designed to be strongly typed and it seems as if Any and AnyObject undermine Swift's type safety.

The reason for introducing Any and AnyObject is primarily for compatibility reasons. I already mentioned that most of the frameworks used for Cocoa development are written in C and Objective-C. Objective-C defines the id type, which represents any object. To make sure that Swift and the Cocoa frameworks can work together, the Swift standard library introduced the Any and AnyObject types. We'll learn more about this when we start working with the Cocoa frameworks.

4. Classes and Structures

Classes

If you're familiar with object-oriented programming, then you should already be familiar with classes. Classes are pretty ordinary in Swift. Take a look at the following example in which we define a class, Boat, with two properties, speed and lifeboats, and a method, deployLifeboats().

Initializing and modifying an instance of the Boat class is straightforward as you can see below. Calling a method on an instance isn't magical either. The basics of Swift classes are easy to understand. Right?

Structures

Let's now create a structure that looks surprisingly similar to the Boat class and find out what sets classes and structures apart in Swift.

The following example reveals the most important difference between Swift classes and structures.

Difference Between Classes and Structures in Swift

This example illustrates that classes are passed by reference while structures are passed by value. What does that mean? We initialized a Boat instance, assigned it to boat1, and set its speed property to 11.0. We assigned boat1 to boat2. This means that boat2 has a reference to boat1. Both boat1 and boat2 point to the same Boat instance. The result is that setting the speed property of boat2 also modifies the speed property of boat1.

This isn't true for structures. We repeat the same steps using the Ship structure. The end result is different though. By assigning ship1 to ship2, the value of ship1 is copied and stored in ship2. This means ship1 and ship2 point to different objects, different instances of the Ship structure. This is a very important concept to grasp so make sure you understand this before continueing.

Consequences

You've already been introduced to the common data types defined by the Swift standard library. What I didn't mention in that discussion is that every Swift data type we discussed so far is a structure.

Every collection type in Swift, for example, is a structure. Every number type is a structure. This is important to know and understand, especially if you come from a language that passes some of these types by reference, such as Ruby and Objective-C.

More Differences

There are a number of other differences that set classes and structures apart in Swift. Classes support inheritance while structures don't. In the following example, we define a class Speedboat that inherits from the Boat class. The Boat class is the parent class or superclass of Speedboat.

Because Boat is the parent class of Speedboat, Speedboat inherits the properties and methods defined in the Boat class. The example illustrates this. Even though the implementation of the Speedboat class is empty, the Speedboat instance, myBoat, has speed and lifeboats properties as well as a deployLifeboats() method.

A more subtle difference that sets classes and structures apart is type checking at runtime. You can check the type of a class instance at runtime while this isn't possible for structure instances.

5. Optionals

Optionals are an integral part of the Swift programming language. Let's find out what optionals are and why they are so important. A variable must be initialized before it can be used. Take a look at the following example to understand what this means.

If you're used to working with strings in other programming languages, then you may be surprised that the compiler throws an error. Let's see what that error tells us.

Variable Not Initialized

In many programming languages, variables have an initial default value. In Objective-C, for example, the string in the following code snippet is equal to nil.

What Is an Optional?

Swift uses optionals to encapsulate an important concept, a variable or constant has a value or it hasn't. It's that simple in Swift. To declare a variable or constant as optional, we append a question mark to the type of the variable or constant.

The variable str is no longer of type String. It is now of type optional String. This is important to understand. The consequence is that we can no longer directly interact with the value of str. The value is safely stored in the optional and we need to ask the optional for the value it encapsulates.

Forced Unwrapping

One way to access the value of an optional is by forced unwrapping the optional. We can access the value of str by appending a ! to the variable's name.

It's important that you are sure that the optional contains a value when you force unwrap it. If you force unwrap an optional that doesn't have a value, Swift throws an error and your application crashes.

Forced Unwrapping an Optional Without a Value

Optional Binding

There is a safer way to access the value of an optional. The following example shows how we can safely access the value stored in str, which is of type String?.

We first check if str is equal to nil before we print its contents. In this example, str doesn't have a value. This means it won't be forced unwrapped by accident.

There's a more elegant approach known as optional binding. In the following example, we assign the value stored in the optional to a temporary constant. The value of the optional str is bound to the constant strConst and made available in the if clause of the if statement. This approach also works for while statements.

What Is nil?

If you're coming from a language like Objective-C, then you most certainly know what nil is. In Objective-C, nil is a pointer to an object that doesn't exist. Swift defines nil a bit differently and it's important that you understand the difference.

In Swift, nil means the absence of a value, any value. While nil is only applicable to objects in Objective-C, in Swift nil can be used for any type.

Did You Miss the Semicolon?

Have you noticed that we haven't used any semicolons in the examples of this tutorial? In Swift, there's no need to use semicolons, because the compiler is smart enough to understand when one statement ends and another one begins. If you really miss using semicolons, then it's fine to add them. Keep in mind, though, that the language guide recommends to omit semicolons.

Conclusion

Even though we've only scratched the surface in this tutorial, you now have a basic understanding of the Swift programming language. In the next tutorial, we'll explore another key component of the language, closures and functions. We'll also discuss protocols and access control.

If you have any questions or comments, you can leave them in the comments below or reach out to me on Twitter.

Tags:

Comments

Related Articles