Dive into the Swift programming language with this quick start guide that will have you up and running in no time.
What you will learn…
- How to work with playgrounds
- The basics of the Swift programming language
- Grouping multiple values into a tuple
- How to work with optionals
- String fundamentals
- Control flow
What you should know…
- A familiarity with at least one programming language
Swift is Apple’s innovative new programming language. If you’ve always wanted to develop iOS or OS X apps but were put off by the seeming complexity of Objective-C then this might be the perfect time to give it a try.
Swift is modern and has been designed to be friendly to new programmers. It’s expressive and is as enjoyable to use as a scripting language. In fact, if you’re coming from a JavaScript or ActionScript background then large parts of Swift will actually feel familiar to you.
This tutorial series however isn’t just for ECMAScript programmers. Those already familiar with Objective-C, or from a Java or C background, will also find this a good resource for transitioning over to Swift.
Everything covered in this series of tutorials can also be found in Apple’s own official guide to the Swift programming language. The intention here however is to focus on the elements of the language that are required to get newcomers up and running as quickly as possible. If you have the time and want the full detail then I highly recommend you head straight over to Apple’s Swift Programming Language Guide instead.
Getting Started
Let’s start by installing Xcode 6. You can download it from the Swift Resources page. Of course, you’ll need a Mac and OS X to run Xcode, but if you’re on a different platform then you can still read through this tutorial and learn a lot about the language.
Once installed, launch Xcode 6. You’ll be greeted by Xcode’s Welcome window. From here you can immediately start experimenting with Swift by opening a new playground file. But what is a playground?
Playgrounds make writing Swift code easy and fun. When working from a playground file you can type lines of code and see the result immediately. There is no need to create and build an Xcode project. Playgrounds is a perfect interactive environment for learning Swift and trying out new ideas. For that very reason we’ll use it during this tutorial series.
Okay, let’s create a playground to work from.
Do that by selecting the Get started with a playground option from Xcode’s Welcome window. A new window will appear where you can set the name for your playground file and your target platform. Ensure the target platform is set to iOS
and name your file Quick Start Guide Part 1
. Click Next then select a suitable location on your hard drive to save the playground file to. Finally, click Create.
Congratulations! You’ve just created your first ever playground file and are now ready to start experimenting with the Swift programming language. You’ll be presented with a window that’s split into two columns.
On the left-hand side is where you’ll enter your Swift code. In fact, you should see some default code already sitting there. On the right is a sidebar where the results of your evaluated code will be shown.
Your playground window also provides a timeline assistant, which comes in handy when working with code that runs over time. For example, if you write a loop, you can watch its progress in graph form, with the value of each of the loop’s variables clearly charted over time. However, focusing on the sidebar for the time being will be more than enough to get us up and running.
Feel free to delete the code that’s already within your playground. Now let’s get the ball rolling.
Your First Program
Take a look at the following line:
If you were to save the above within a text file and give it the .swift
extension, you’d have written the simplest program you can write with the Swift programming language.
That’s right, just a single line of text and you have a working program. Any code written at the global scope is used as your program’s main entry point, and there’s no need to import a library to handle output of your string either.
You may also notice one curious omission. There’s no semicolon at the end of the line. Semicolons aren’t required at the end of every statement. Adding semicolons to the end of a statement is a hard habit to break. Hang on in there though and you’ll soon learn to live without them.
Try the above example out by typing it into your playground window. Hitting the Enter key will result in Hullo World!
being displayed within the sidebar.
Hullo World!
would have been displayed within Xcode’s console panel rather than your playground’s sidebar.
There are various destinations that text can be written to depending on the context in which you are running Swift. It’s therefore better to refer to those destinations collectively as the appropriate output. We’ll use that term throughout.
Comments
Comments in Swift are similar to comments in most languages. Here’s an example of a single-line comment:
Comments can also span several lines:
check to see if the collision killed them. */
Unlike most languages, multiline comments can also be nested inside other multiline comments. This is particularly useful if you need to quickly comment out large blocks of code that already contain multiline comments.
Variables and Constants
Variables are declared with the var
keyword. Here’s an example of a variable that stores the number of lives a player has:
Constants can also be declared. Use the let
keyword:
You can also declare multiple variables or multiple constants on a single line:
Use constants for any values that will not change during the lifetime of your program.
When you declare a constant you must also provide it with an initial value. Unlike a constant, a variable does not require an initial value when being declared. However, a value must be assigned before the variable is actually used.
maximumLevel
on one line then attempt to change its value on the next:
maximumLevel = 25
You’ll receive the following error:
Types and Type Inference
You probably noticed that a type was not specified for any of the variables or constants. Swift can infer the type you intend to use from the initial value you provide. The following declares a constant that stores a string:
When you need to be clear about the type being used you can specify it by placing a colon after the constant or variable name:
In most situations however, you shouldn’t need to explicitly state the type you intend to use.
Swift provides types for integers, floating-point numbers, strings, characters and boolean values.
Integers
Integers are represented by signed and unsigned types in 8 (Int8
, UInt8
), 16 (Int16
, UInt16
), 32 (Int32
, UInt32
), and 64 (Int64
, UInt64
) bit forms. However, you really don’t need to worry about the specific size of an integer. Instead, use the Int
integer type, which is represented by Int32
on a 32-bit platform, and Int64
on a 64-bit platform. Here is an example:
Alternatively, as discussed earlier, the type can be inferred:
An unsigned integer type, UInt
, is also available:
However, it’s recommended that you use Int
even for values that are known only to be non-negative. This avoids the need to convert between different number types.
Floating-Point Numbers
If you need to store a number with a fractional component or a much larger number than can be stored with an integer type, then use either the Float
or Double
type. A Double
has a precision of at least 15 digits whereas a Float
can have a precision of at least 6 decimal digits:
let value2: Double = 1 / 3
Of course, you can stop worrying about the exact type and let Swift make that decision for you:
Use Double
only when you require the additional precision or to store a number that’s too large to be represented by Float
.
1.0
). This is to ensure that the value3
constant is implicitly declared of type Double
. If two integers had been divided instead, Swift would have incorrectly inferred that an integer type was to be used for your value3
constant, which would have resulted in it being initialised with a value of 0
.
You can test this directly within your playground. Go ahead and enter the following:
let value2 = 1.0 / 3
let value3 = 1 / 3
If you examine the sidebar you’ll notice that value3
contains a value of 0, which is probably not what you expected.
This is a common mistake made by those coming from languages such as JavaScript.
Boolean
Swift has a Bool
type and provides two constant values, true
and false
for you to work with. Here are some examples:
var isAlive = true
let catsHateDogs = true
Of course, with all three variables above, you could have declared each as being of type Bool
. However the use of the Bool
type is inferred by assigning either true
or false
to each.
Strings
Swift represents strings with the String
type, which is essentially a collection of characters:
let sith = “Darth Vader”
As expected, in the example above, the String
type is inferred by the fact that a string literal is used to initialise each constant.
It’s worth noting that a Swift string is a value type. In other words, the value of the string is copied when passed to a function or method. The same is also true when a string is assigned to another constant or variable. This is different to the behaviour of Objective-C where a reference to a string is used instead.
Strings can be concatenated to create a new string:
var surname = “Caleb”
let fullName = forename + ” ” + surname
Strings that are represented by constants cannot be modified once they are initialised.
Printing Values
As you have already seen, you can print a string to the appropriate output (Xcode’s console pane for example) using the global println
function:
You can also print the current value of any variable or constant:
println(name)
It’s also possible to insert variables or constants as placeholders directly within a string. This is done by wrapping the name in parentheses and escaping it with a backslash before the opening parenthesis:
var player2 = “Yoda”
println(“\(player1) vs. \(player2)”)
The example above will print Vader vs. Yoda
to the appropriate output.
Type Conversion
Each number type has a different range. For example, the Int8
type can store any value ranging from -128
to 127
. The UInt8
type has a range from 0
to 255
. A variable or constant whose value is too small or too large for its specified type will result in a compile-time error. For example, this will result in an error:
In other words, Swift does not attempt to automatically handle numeric overflow. By refusing to do so it prevents hidden conversion errors. Instead, if you are dealing with different numeric types then you must explicitly convert all your values to the same type. Take a look at the following:
let remainingTime: UInt8 = 12
let finalScore = numberOfKills * UInt16(remainingTime)
In the example above, the value of the finalScore
constant is calculated by multiplying the value of numberOfKills
with remainingTime
. However, since numberOfKills
and remainingTime
are both of different types, one of the types must first be converted to match that of the other. In our example, this is done by calling UInt16(remainingTime)
to convert the remainingTime
constant to the same type as numberOfKills
.
UInt16(remainingTime)
is an example of a type’s initializer being called and passed an initial value. This is known as initializer syntax and can be used to initialise a variable or constant of any numeric type. Here’s a similar example, but this time, both constants are converted to Int8
types before the final score is calculated:
let bonusPoints: Int8 = -2
let finalScore = Int8(numberOfKills) + bonusPoints
Conversion between floating point and integer number types must also be handled explicitly. Here’s an example, where the numberOfKills
variable is converted from an Int
to a Double
:
var remainingSeconds = 2.45
let finalScore = Double(numberOfKills) * remainingSeconds
It’s also possible to convert a floating-point value to an integer, although there will be a loss of precision:
let pi = 3.14
let height = 5.9
let temperature = -3.9
println(“remaining seconds: \(Int(remainingSeconds))”)
println(“pi: \(Int(pi))”)
println(“height: \(Int(height))”)
println(“temperature: \(Int(temperature))”)
When run, the following will be appear in the appropriate output:
pi: 3
height: 5
temperature: -3
A conversion from floating-point to integer is always truncated. For example, 5.9
will become 5
, whereas -3.9
will be converted to -3
.
Tuples
You can group multiple values into a single compound value through the use of a tuple. The values stored within a tuple do not have to be of the same type. The following example groups information about the non-Retina iPad’s screen resolution:
Remember, Swift infers the type of each value. However if you did want to be explicit:
You can access an individual value within a tuple by specifying that value’s position. The following example obtains the screen resolution’s width and height:
var height = iPadStandard.1
println(“The screen is \(width) pixels wide and \(height) pixels high.”)
Rather than working with index positions you can also decompose a tuple like this:
println(“The screen is \(width) pixels wide and \(height) pixels high.”)
The example above creates three variables (width
, height
, and screenType
) and assigns each of them to a value within the tuple.
Notice that we had no need for the screenType
variable in our example. You can use an underscore to ignore values you don’t require when decomposing a tuple:
println(“The screen is \(width) pixels wide and \(height) pixels high.”)
You can also assign a name to individual elements within a tuple. Here’s our non-Retina iPad example again but with a name associated with each element:
var width = iPadStandard.width
var height = iPadStandard.height
println(“The screen is \(width) pixels wide and \(height) pixels high.”)
Tuples are ideal for temporarily storing groups of related data. They are also an extremely powerful means of returning multiple values from a function or method. They aren’t however, suitable for representing complex data structures.
Now create a variable named currentScreen
and arbitrarily assign it to the various constants. Using that variable, extract values from each and print them using the printlin()
function.
Optionals
It was stated earlier that a variable or constant must be assigned a value before it can be used. How do we handle variables that, for one reason or another, may not hold a value at various points during your program’s execution? Swift provides nil
, which is a special value that represents a valueless state.
You therefore might reasonably expect to see code like this in Swift:
After all, not everyone has a middle name. Unfortunately Swift variables cannot be nil
. They must always have a value associated with them.
In such situations you would use an optional variable instead. By using an optional you are saying that the variable will either have a value, or no value at all. An optional type has a question mark placed after it. Here’s our middle name example again, but this time using an optional:
Notice that, in this case, the optional string type has to be explicitly stated. It’s also defaulted to nil
.
Let’s set our middleName
variable to something:
Forced Unwrapping
Now that we have a value stored within our optional, we can consider using it. To retrieve a value from an optional you have to unwrap it by placing an exclamation mark at the end of the optional’s name:
Before you can unwrap an optional though, you must first check that it contains a value. In other words, you must check that your optional is not nil
.
println(“James \(middleName!) Kirk”)
}
if
statement in the example above but haven’t yet covered control flow yet. It should be fairly obvious how it works though. By using the exclamation mark to obtain the optional’s value, you are stating that you are absolutely sure that the optional does actually contain a non-nil
value. This is known as forced unwrapping, and doing so on a variable that contains nil
will result in a runtime error.
Create a few optional constants. Each optional should be initialised to a string literal that contains the name of a friend. Print each of your friend names (one println()
for each friend) and check the result in the sidebar. Verify that you’ve actually unwrapped your optional by checking that the keyword Optional
doesn’t appear in the sidebar next to each of your println()
statements.
Now go back and initialise each of your constants to nil
. Ensure that nothing is now being printed to the sidebar and confirm that you aren’t receiving any runtime errors.
Optional Binding
As an alternative to using an if
statement before obtaining an optional’s value, you can also use a technique known as optional binding. It works by checking that an optional contains a value and then storing that value in a temporary variable or constant for you to work with. Here’s our middle name example again, but this time taking advantage of optional binding:
middleName = “Tiberius”
if let name = middleName {
println(“James \(name) Kirk”)
}
The example above checks to see if the middleName
optional contains a value. If it does then it sets a new constant called name
to the value contained within middleName
. That constant is then made available within the first branch of the if
statement.
Also, since the name
constant has already been initialised with the value stored within the optional, there is no need to forcibly unwrap it with an exclamation mark. The name
constant is a string rather than an optional. In other words, the name
constant is a non-optional type.
Implicitly Unwrapped Optionals
Sometimes you’ll want to work with an optional that you know for sure will always have a value after it’s first set. For example, you may write a video game that loads the current highest score from the file system. Initially your variable will contain nil
while the high score is being loaded, but once that high score is set, the structure of your game guarantees that your variable will always contain a score.
In such cases, checking and unwrapping the optional every time you want to access its data is unnecessary. You can actually remove the need to do this by using an implicitly unwrapped optional.
An implicitly unwrapped optional is created by placing an exclamation mark after its type rather than a question mark. Here’s an example:
Once the highScore
variable has been set to a value you can then use it like any non-optional value:
println(“The high score is: \(highScore) points”)
Notice that there was no need for an exclamation mark immediately after the highScore
variable on either lines.
Basic Operators
Swift’s basic operators will be familiar to most developers. It also provides support for a few special operators such as the nil coalescing operator and two range operators. We’ll cover the range operators shortly but will leave the nil coalescing operator for another day.
Assignment Operator
We’ve already seen the assignment operator (=
) used to initialise variables and constants, and of course it can just as easily be used to assign the value of one variable to another.
Unlike many languages, Swift’s assignment operator does not return a value. The following statement isn’t valid:
// Do something
}
This feature prevents the assignment operator from accidentally being used when the equal-to (==
) operator was actually intended.
Arithmetic Operators
As you would expect, the standard arithmetic operators (+
, -
, *
, and /
) are all supported by Swift.
Remainder Operator
Swift supports the modulo operator (%
). Its implementation is slightly different to that found in most other languages and is therefore better described as the remainder operator. Here are some examples:
9 % -4 // equals 1
-9 % 4 // equals -1
-9 % -4 // equals -1
Unlike some other languages, Swift’s remainder operator can work with floating-point numbers:
10.5 % 6.4 // equals 4.1
Increment and Decrement Operators
The increment (++
) and decrement (--
) operators behave as expected:
var b = a++ // b equals 1
var c = ++a // c equals 3
var d = --a // d equals 2
var e = a-- // e equals 2
Compound Assignment Operators
Compound assignment statements are also supported. Here are a few examples:
a += 4 // a equals 5
a -= 1 // a equals 4
a *= 2 // a equals 8
a /= 4 // a equals 2
Comparison Operators
Swift supports all the usual comparison operators found in most other languages: equal to (a == b
), not equal to (a != b
), greater than (a > b
), less than (a < b
), greater than or equal to (a >= b
), and finally, less than or equal to (a <= b
).
Logical Operators
Swift has support for the three standard logical operators: logical AND (a & b
), logical OR (a | b
), and logical NOT (!a
).
Of course, you can also combine multiple logical operators to create longer compound expressions.
Range Operators
Swift provides a closed range operator and a half-open range operator. These operators are useful when expressing a range of values.
The closed range operator (a...b)
defines a range from a
to b
, and includes both a
and b
. The closed range operator is useful when iterating over a range of values with a for-in
loop. Here's an example:
println(i)
}
The example above will print the following to the appropriate output:
1
2
3
4
5
The half-open range operator (a..<b)
defines a range from a
to b
, but does not include b
:
This will result in the following being sent to the appropriate output:
1
2
3
4
For Loops
Swift provides a for
loop and a for-in
loop. Let's begin with the for
loop.
For Loop
The general structure of a for
loop should look familiar. Take a look at this code snippet:
The only real difference between a for
loop in Swift compared to most other languages is that parentheses aren't required. The example above will result in the following being printed to the appropriate output:
index: 1
index: 2
index: 3
index: 4
println()
call. You should see the text (5 times)
and an icon of a dot to the right of that.
If you click that icon, the timeline assistant pane will open and you'll be able to see the result from each iteration of your loop.
Block scope is important. Variables and constants declared within a loop are only valid within the scope of the loop. This includes any variables and constants declared as part of the for
loop's initialisation block. This often trips-up developers who have a background in ECMAScript-based languages such as JavaScript and ActionScript since these scripting languages don't support block scope.
For-In Loop
The for-in
loop is used to iterate over collections of items. This can include such things as a range of numbers, items in an array, the contents of a dictionary, or the characters in a string.
We'll look at a simple example here, then see more uses for the for-in
loop in part two of this series:
println("index: \(index)")
}
This is functionally equivalent to our for
loop example and will result in the same output being printed. In the example above, the closed range operator (...
) is used to define a collection of numbers from 0 to 4 inclusive. On each iteration, a constant named index
is created and set with the current value from the range.
By default, a for-in
loop uses a constant, therefore there is no need to explicitly use the let
keyword when providing the constant with a name.
As with the for
loop, block scope is important. The for-in
loop's constant only exists within the scope of the loop.
for-in
loop rather than a for
loop.If Statements
Swift provides two types of conditional statements: the if
statement and the switch
statement. We'll discuss the switch
statement in a future article and focus on the various flavours of the if
statement at the moment since they are more commonly used.
If Statement
The if
statement, like much of the Swift language, will look familiar to anyone who has programmed before. Here it is in its simplest form:
if energy == 0 {
println("Vader's lightsaber cuts through you.")
}
As with for
loops, parentheses aren't required when working with if
statements.
If-Else Statement
Of course, you can add an else clause to your if
statement:
if energy > 0 {
println("The force is strong with you.")
} else {
println("Vader's lightsaber cuts through you.")
}
If-Else If-Else Statement
Additional clauses can be considered by using the else if
keywords:
if energy > 40 {
println("The force is strong with you.")
} else if energy > 20 {
println("You have much to learn.")
} else if energy > 0 {
println("Your powers are weak old man.")
} else {
println("Vader's lightsaber cuts through you.")
}
The final else
clause isn't mandatory and can be dropped.
Next Time
I hope you've found from this tutorial that there's nothing particularly difficult about the Swift programming language. No matter what your development background is, everything covered (perhaps with the exception of optionals) should have felt familiar. We're certainly not in a position to go ahead and get something running on a device yet, but stick with this series and we will get there.
In the next tutorial we'll take a look at Swift's two collection types: arrays and dictionaries. We'll also take a closer look at a few subjects that we touched upon today. Specifically, we'll spend more time looking at strings, and also cover a few more control flow statements including while loops and the switch
statement.
In the meantime keep experimenting with playgrounds. If there are things that you haven't quite grasped then spend a little time going back over this tutorial and trying things out until they're clear in your head.
See you in part two.