Swift - Learn Apple's New Programming Language Step By Step

Learn the basics of new language that will help you go on to programme on Apple iOS 8 and Mac OSX
  • Lectures 234
  • Video 16 Hours
  • Skill level all level
  • Languages English
  • Includes Lifetime access
    30 day money back guarantee!
    Available on iOS and Android
    Certificate of Completion

How taking a course works


Find online courses made by experts from around the world.


Take your courses with you and learn anywhere, anytime.


Learn and practice real-world skills and achieve your goals.

Course Description

Become one of the world's earliest Swift developers with this introductory course on Apple’s new programming language.

  • Initial Setup and Swift Basics
  • Operators, Strings, Characters, and Collection Types
  • Evolving from Objective C
  • Control Flow

A Modern Language Evolved from Objective C

Swift is a multi-paradigm programming language developed by Apple for use with iOS and OS X. Designed to replace Objective C, work began on Swift in 2010 and the first mobile app was debuted in June 2014 at the Worldwide Developers Conference. Despite its goal of replacing Objective C, Swift is capable of working alongside the more dated Objective C language while using the Cocoa and Cocoa Touch frameworks.

Swift is built with the LLVM compiler included in Xcode 6 beta, and uses the Objective-C runtime, allowing Objective-C, Objective-C++ and Swift code to run within a single program. During it’s debut, Swift was described as “Objective C without the C” by Apple’s VP of Software Engineering Craig Federighi.

Contents and Overview

Through 95+ video lectures and 4 hours of content, you will be lead through setting up Swift locally, the basics of the language, how it compares to other common languages (including Objective C), and how to get started on new projects.

The course is designed to provide a comprehensive introduction to Swift, so that you can begin experimenting right away. Upon completion, you will understand the foundations of Swift code and will be able to develop custom applications. You will also get experience working with Xcode's new .playground file. By enrolling in this course you will be months ahead of other developers attempting learn the new Swift programming language by navigating Apple's 500-page instructional document.

Course material is regularly refreshed to include all of the newest updates and information, and since you’re granted lifetime access upon registering, you can rely on this course to keep your Swift skills on the cutting edge.

What are the requirements?

  • Developer access to Xcode 6 beta
  • A Mac computer that can run Xcode 6
  • Enrolled in a paid developer program (iOS or Mac is fine)

What am I going to get from this course?

  • Over 234 lectures and 15 hours of content!
  • Video walkthroughs showing you how to use Swift
  • Work with Xcode's new .playground file

What is the target audience?

  • Objective-C developers wanting to learn Swift
  • New programmers wanting to learn Swift

What you get with this course?

Not for you? No problem.
30 day money back guarantee

Forever yours.
Lifetime access

Learn on the go.
Desktop, iOS and Android

Get rewarded.
Certificate of completion


Section 1: Swift - The Introduction
Welcome - What Will You Learn from This Course

You can download Xcode for free now! You still have to register as a developer with Apple but follow the link on this blog https://developer.apple.com/swift/blog/

Link to Swift eBook by Apple

Another eBook Apple has released!

Section 2: The Basics
Constants and Variables

A lot of the information in this lecture was covered in the previous lecture but I wanted to have this separate lecture to really drive home the value of Unicode for naming variables. Feel free to skip!

Type annotations
Type Aliases
Floating Point Numbers
Numeric Literals
Numeric Type Conversion
The Basics - Quiz
5 questions
Section 3: Basic Operators
Assignment Operator
Arithmetic Operators
Remainder Operator
Increment and Decrement Operators
Compound Assignment Operators
Comparison Operators
Ternary Conditional Operators
Range Operators
Logical Operators
Basic Operators Quiz
5 questions
Basic Operators Challenge
Basic Operators Answers
Section 4: Strings and Characters
String Literals
Initializing an Empty String
String Mutability
Strings Are Value Types
Working with Characters
Counting Characters
Concatenating Strings and Characters
String Interpolation
Comparing Strings
Uppercase and Lowercase Strings
Strings and Characters Quiz
5 questions
Strings and Characters Challenge
Strings and Characters Answers
Section 5: Collection Types
Dictionary Literals
Changes In Arrays/Dictionaries
Array Literals
Accessing and Modifying an Array
Iterating Over an Array
Creating and Initializing an Array
Accessing and Modifying a Dictionary
Iterating Over a Dictionary
Creating an Empty Dictionary
Mutability of Collections
Collection Types Quiz
5 questions
Collection Types Challenge
Collection Types Answers
Section 6: Control Flow
For-In Loops
For-Conditional-Increment Loops
While Loops
If Statements
Switch Statements
Switch Statements and Tuples
Value Bindings
Where Clause
Labeled Statements
Control Flow Quiz
5 questions
Control Flow Challenge
Control Flow Answers
Section 7: Functions
Return Values
External Parameter Names
Default Parameter Values
Variadic Parameters
Constant and Variable Parameters
In-Out Parameters
Function Types
Function Types as Parameter Types
Function Types as Return Types
Nested Functions
Functions Quiz
5 questions
Functions Challenge
Functions Answers
Section 8: Closures
Closures Intro
Closures Expressions
Trailing Closures
Capturing Values
Closures are Reference Types
Closures Quiz
2 questions
Closures Challenge
Closures Answers
Section 9: Enumerations
Enumeration Syntax
Enumerations With a Switch Statement
Associated Values
Raw Values
3 questions
Enumerations Challenge
Enumerations Answers
Section 10: Classes and Structures
Classes and Structures Quiz
4 questions
Section 11: Properties
Properties Quiz
4 questions

Instructor Biography

Nick Walter , Swift Developer

I'm Nick Walter, an iOS developer that has been focused on mobile app design and creation for over 3 years. My involvement in the iOS community started off with a bang, and in 2013 I was one of 25 students worldwide to be invited to Apple's "Cocoa Camp." Within my community, I am also co-president of an Apple developer group called "Cocoa Heads."

I've always had an itch to make things, but growing up in a small town I had limited access to programming resources. This frustration drove my early interest in online education. After experimenting with various companies, learning styles, and teaching processes, I've adopted the best strategies and used them in my courses. My experience as an online student has directly influenced my teaching style, and I am now proud to help students all over the world with their online learning goals.

Since the announcement of the new Swift programming language by Apple, I have buried myself in the Apple documentation and any online resource that is available. In my first Swift course, I provide students with a detailed explanation of the topics and skills needed to learn Swift, an overview of the basic features of the new language, and get you started to begin building your first products.

Prior to teaching the internet's first course on Swift, I have created 5 iOS apps from scratch that are currently live in the App Store and being used by thousands of users worldwide. Using my experience launching my own apps, I'll walk you through the shortcuts that can save you time and frustration from having to teach yourself.

Instructor Biography

Kyle Clegg , iOS Developer

I am a Utah based iOS developer that enjoys creating apps with Objective-C and Swift. I've published 5+ apps to both the App Store and Google Play Store, building up a wide range of mobile development skills across both platforms in the process. I am passionate about writing truly great apps, the kind that care about details beyond just a great UI, from the UX down to each line of code.

I graduated in June 2014 as a Master of Information Systems with a minor in Computer Science. During my time in school I participated in two summer internships as an app developer and worked as a TA for the iOS programming class after having taken the class myself the previous year. I was also able to attend WWDC and Cocoa Camp during the summer of 2013. These experiences have given me numerous opportunities to learn about iOS development from the people that created it! I enjoy learning about iOS development as well as helping others do the same.

Having some educational background in programming, but none in Apple's world, I identify with self-taught programmers. There's nothing like the first time you code something and run it on your phone. It's a feeling of empowerment knowing that with the right idea, focus, and delivery you could be the next person to create an awesome app loved by millions.

A couple of years ago I was a complete noob trying to learn iOS development. The blog posts, YouTube vids, and tutorials sites helped me SO much, as I preferred the hands-on approach of doing as opposed to digging through dense programming books that often lacked any real-world applicable example. I'm stoked to be involved in teaching a Swift course and hope to help many of you learn Swift and get on your way to writing awesome apps!

Join the biggest student community


Hours of video content


Course Enrollments




Average Rating
  1. 5 Stars
  2. 4 Stars
  3. 3 Stars
  4. 2 Stars
  5. 1 Stars
    • Kamleshwar Dhuria

    Wonderful Cource coverage

    Contents are informative and helped with understand well.

    • Juan Montesinos

    Missing subtitles

    At the end of the Closures section, the subtitles are not available anymore. It is very important for students from another countries.

    • Richard Pitre

    Thorough teaching

    Covers the entire spectrum of Swift!

    • Faisal Ahmed

    Best Course for Swift 1.0

    I would highly recommend Nick as a tutor to get your feet wet in the sea of Swift. I started this course being clueless about the language and can confidently say that the things i've learned and the notes I've taken during learning this course is better than the official Apple documentation that they have. Thanks Nick, great job!

    • Garrett Graf

    Perfect for beginners

    I've been try a lot of tutorials and courses, and I learned more from this than any other tutorial and class so far. It was nice to actually step through each area of Swift, instead of just having a tutorial say, "next, we want to do this in your app, here is your code you need". This came a foundation now, and going through app building tutorials already make more sense to me now.

Show more reviews
Ready to start learning?
Preview this course

Top 10 Tips to Speed up Swift Learning

Tip #1 - Use Type Inference to Simplify Variable Declarations

In Objective C (as well as many other languages), every time a variable is declared and contextually initialized, the type must always be specified. For example:

int number = 0;
double pi = 3.14;
NSString *city = @"Boston";
NSArray *array = [[NSArray alloc] init];

Swift is a strongly typed language, meaning that the type of a variable must be determined at compilation time and cannot be changed during the variable's lifetime. In many cases, the compiler is able to automatically determine the type from the context, and in those cases specifying the variable type is redundant and can be omitted. This feature is called type inference.

The above code can be literally translated to Swift as:

var number: Int = 0
let pi: Double = 3.14
var city: String = "Boston"
var array: NSArray = NSArray()

and can also be rewritten more concisely as:

// '0' is an integer number, so 'number' is 'Int'
var number = 0

// '3.14' is a floating point number, so 'pi' takes the
'Double' type let pi = 3.14

// 'Boston' is a string, so 'city' takes the 'String' type
var city = "Boston"

// Creating an instance of 'NSArray', so array is of
NSArray type var array = NSArray()

In the above cases, all variables are initialized with literal values or with new instances whose respective types are unambiguously determined at compilation time.
Type inference also works with values returned by functions and methods. If we implement a square function working on integers:

func square(op: Int) -> Int {
     return op * op

We can assign its return value to a variable with no need to specify its type, because it is inferred by the Int return type:

let sixteen = square(4)

Type Inference, Method Overloads, Return Types and Ambiguities

In Swift, it's possible to overload methods in a way not available in many other language: differing by the return type only.
For example, we could provide a new implementation of the square function defined above, but returning a Double:

func square(op: Int) -> Double {      let value: Int = square(op)      return Double(value) }

Now we've got 2 functions having the same square name, both taking an integer parameter, but one returning an integer and the other one a double.
The first thing to notice is that type inference for variable declaration no longer works:

let sixteen = square(4) // Compilation error:
"Ambiguous use of 'square'"

That's because the compiler is not able to determine which of the 2 overloads to call. This is one of the rare cases where declaring and initializing a variable requires the type to be specified. So the following 2 cases work:

let intResult: Int = square(4)
let doubleResult: Double = square(4)

In both cases, the correct version of the function to invoke is determined by the type of the variable the return value is assigned to. Another way to resolve the ambiguity is by performing an explicit downcast of the return value:

square(4) as Int

will invoke the version returning an integer, whereas:

square(4) as Double

will invoke the overload returning a double.

Tip #2 - Value Types Are Passed by Copy
var friends = ["John", "Robert", "Anna", "Lucy"]
var friendsCopy = friends

If a new friend name is added to the copy:


it is correctly listed and printed:

[John, Robert, Anna, Lucy, Tom]

but friends still contains the original list:

"[John, Robert, Anna, Lucy]"

so without the change. Why is that happening?

Reference types and value types

Types in swift can be divided into 2 different categories:

  • reference types
  • value types

Classes and closures fall in the first category, and everything else in the second, which includes:

  • structures (struct)
  • enumerations (enum)
  • basic data types (Int, Float, etc.)
  • tuples
Reference types

When a reference type is instantiated and assigned to a variable, a reference to the instance and not the instance itself is assigned to the variable. If we assign a new instance of UIView to a variable:

let view1 = UIView()

and next we copy into another variable:

let view2 = view1

both variables will contain references to the same UIView instance, because the reference to the instance, and not the instance itself is copied. Consequently, any mutating action performed from view1 will be visible from view2 and vice-versa, because the mutation is performed on the same instance.

Value types

Different from reference types, when a value type is instantiated and assigned to a variable, the value itself is assigned. So the variable contains the value. A direct consequence is that when the variable is copied, the value, and not a reference to it, is copied. Let's consider the following code:

var int1 = 0
var int2 = int1

Intuitively, we know that if int1 is changed int2 will keep its value and won't be affected by the int assignment:

int1 = 10
int2 == 0 // evaluates to true

Back to our friends list, arrays (as well dictionaries and sets) in Swift are implemented as structures, which are value types. So when an array assigned to a variable:

var friends = ["John", "Robert", "Anna", "Lucy"]

is copied into another variable:

var friendsCopy = friends

a copy of it is created and assigned to the new variable, and each of the two instances will live their own life.

Before thinking that value types are slow and inefficient because every time they are assigned to variables or passed as arguments a copy is created, it's very important to know that the compiler plays an important role here by optimizing their usage. So if an array assigned to a variable a is copied to another variable b, but none of the two instances is mutated, then the compiler is smart enough to avoid creating a copy and manage to have both variables point to the same data.

Tip #3 - Functional Side of Swift Arrays

In development it's frequent to have to transform a list of data into something else, which usually is:

  • a subset of the original list
  • a similar list obtained by applying a transformation to each element of the original list
  • a pseudo-scalar value obtained by recursively applying an operator to all elements and accumulating the intermediate result

commonly known respectively as filter, map, and reduce.


In Objective C, any of the above transformations can be implemented using a for-each loop. Let's consider the following array of daily temperatures:

NSArray *dailyTemperatures = @[

One of the possible ways to calculate the average temperature is:

double average = 0;
for (NSNumber *temperature in dailyTemperatures) {
     average += temperature.doubleValue;
average /= dailyTemperatures.count;

Using the reduce method of Swift arrays instead, the same code can be rewritten as:

let dailyTemperatures = [34.0, 46.0, 55.0, 43.0, 76.0, 88.0, 56.0, 58.0]
let average = dailyTemperatures.reduce(0.0, combine: +)
/ Double(dailyTemperatures.count)

The most interesting piece of code is the following:

dailyTemperatures.reduce(0.0, combine: +)

which calculates the sum of all array elements.

By giving an initial value and a closure taking 2 parameters:

  • the accumulated value calculated at the previous iteration (or the initial value for first iteration)
  • an array element

the reduce method iterates over all of its elements, invoking the closure for each element and at the end returning the accumulated value.

In the above case the + function is used - for clarity, it's equivalent to writing:

dailyTemperatures.reduce(0.0) { (initial, element) in
     return initial + element


If we want to convert the array of temperatures from Fahrenheit to Celsius, in Objective C we'd use a for-each loop similarly to the previous case.

In Swift, instead we can use the map method, passing a closure responsible of transforming each element which takes an array element as input and returns the transformed element as output. The map method in turn returns an array of the same length as the original, with the values replaced by the transformed ones:

let dailyCelsiusTemperatures = dailyTemperatures.map
{    (value) in
     return (value - 32) / 1.8

Note that the original and transformed types don't have to be the same. For instance, it can be a string:

let dailyCelsiusTemperatures = dailyTemperatures.map
{    (value) in
     return String(format: "%.2f", (value - 32) / 1.8)


This is the most intuitive of the 3 features, again implementable in Objective C using a for-each loop, but invocable in Swift at the cost of one single call. If we want, for example, to retrieve the subset of temperature above 32:

let warmerTemperatires = dailyTemperatures.filter {    (value) in
     value > 70
which returns [76, 88]

Combining Filter, Map and Reduce

Why are these 3 methods so important? Because besides simplifying the code when individually used, they can be chained together, performing complex transformations with just a few lines of code.

Real Example #1: Building a List of Emails

Let's look at a real example of their usage. We have a User entity, which has an optional email field:

struct User {
     let id: Int
     let email: String?

     init(id: Int, email: String? = nil) {
         self.id = id
         self.email = email
     } }

We want to send an email to all users having a valid email address, so we need to extract a list of email addresses from a list of users:

let users = [
     User(id: 1, email: "q@udemy.com"),
     User(id: 2, email: "w@udemy.com"),
     User(id: 3),
     User(id: 4, email: "e@udemy.com"),
     User(id: 5),
     User(id: 6),
     User(id: 7, email: "r@udemy.com")

Combining filter with map, that's pretty easy:

let emails = users
     .filter { $0.email != .None } // Filter all users
     having a valid email
     .map { $0.email! } // For each element, return the
     email address

The same result is obtained using reduce only, obtained by:

  • setting the initial value to an empty array of strings
  • for each element, returning the array obtained at the previous step (or the initial empty array for the first value) after appending the email of the current user if not nil

and implemented in either long form:

let emails = users.reduce([String]()) { (previous, user) in
     if let email = user.email {
         return previous + [email]
     return previous

or short form:
let emails = users.reduce([])
{ ($1.email != .None) ? ($0 + [$1.email!]) : $0 }
Real example #2: Calculating the Total Number of Worked Hours

Consider extending the previous User entity by adding a new hoursWorked property:

struct User {
     let id: Int
     let email: String?
     let hoursWorked: String?

     init(id: Int, email: String? = nil, hoursWorked:
     String? = nil) {
         self.id = id
         self.email = email
         self.hoursWorked = hoursWorked

let users = [
     User(id: 1, email: "q@udemy.com", hoursWorked: "40"),
     User(id: 2, email: "w@udemy.com"),
     User(id: 3, hoursWorked: "20"),
     User(id: 4, email: "e@udemy.com", hoursWorked: "25"),
     User(id: 5),
     User(id: 6, hoursWorked: "55"),
     User(id: 7, email: "r@udemy.com")

which is de-serialized from JSON in string format. We want to iterate over all users and calculate the total number of hours. Since the new property is of string type, it must be converted to integer before being usable for arithmetic calculations. One way to achieve that (the long way) could be done in 5 steps:

  1. filter users by keeping the ones having hoursWorked not nil
  2. transform the resulting array into an array of optional integers
  3. filter the resulting array, keeping all non nil values
  4. transform the resulting array into an array of non optional integers (by applying the forced unwrapping operator)
  5. sum all elements up, obtaining the total number of hours
  6. users .filter { $0.hoursWorked != .None } .map { $0.hoursWorked!.toInt() } .filter { $0 != .None } .map { $0! } .reduce(0, combine: +)

A more compact version of the algorithm can be implemented in just 3 steps, with the first 2 shared with the previous method:

  1. filter users by keeping the ones having hoursWorked not nil
  2. transform the resulting array into an array of optional integers
  3. sum all non-nil elements
  4. users .filter { $0.hoursWorked != .None } .map { $0.hoursWorked!.toInt() } .reduce(0) { $0 + ($1 != .None ? $1! : $0) }
Tip #4 - Make things generic

A recurrent case in programming is the need of duplicating an algorithm or a type to work with different data types than the original ones, with the duplicated part differing by the types only and not the actual implementation.

Because Swift is a very strongly typed language and there is no explicit conversion, even among types that might intuitively be considered equivalent (like integers, unsigned integers, etc.), having a generic way to implement algorithms and types is very useful.

Generic programming is one of the most useful and powerful features of modern languages, although they have their roots in old languages like lisp and ada (old doesn't necessarily means obsolete), and it's probably one of the most awaited feature in Objective C, although never brought to life.

Generics is a very complex topic which cannot be described in just a few paragraphs. Let's take a look at 2 simple examples, a generic function and a generic data type.

A Simple Generic Function to Calculate the Minimum of Two Values

A very simple example showing how to benefit from using generics is a function returning the minimum of two values passed as arguments:

func _min(a: Int, b: Int) -> Int {
     return a < b ? a : b

This implementation works for integers only:

_min(1, 2) // returns 1

but it cannot be used, for instance, with 2 unsigned integers:

_min(1 as UInt, 2 as UInt) // Compilation error

Cannot invoke '_min' with an argument list of type '(UInt, UInt)'
The solution consists of making the function generic by specifying a type T in the function signature, and constraining it to adopt the Comparable protocol:

func _min < T: Comparable >(a: T, b: T) -> T {
     return a < b ? a : b

The Comparable protocol is adopted by all types for which the less than and equal to comparison operators are defined, and of course any user-defined type can adopt that protocol. With the new generic implementation, all of these cases work:

_min(1, 2)
_min(1 as UInt, 2 as UInt)
_min("Liam", "Robert")

as well as any other case using a data type implementing the Comparable protocol.

A Generic Type: Implementing a Stack

A data structure is used to group a set of related data together with the purpose of being used in an efficient way. There are several data structures we use every day, like arrays, dictionaries, sets, queues, and so forth.

Although a specific data structure can be implemented to work with a specific data type only, data structures are perfect candidates for being generics. So to be able to store data of any type, with the only constraint that an instance of a data structure must contain elements of the same type.

Swift already provides generic Array, Dictionary and Set structures. We'll take a look at a custom stackimplementation instead.
A stack is a data structure where elements can be pushed at the top of the stack and popped from the top. It is usually referred to as last in, first out, or LIFO for short, because the first element extracted at any time is the one that's been inserted last and not previously extracted yet.

A good real-world comparative example is a stack of dishes: the last dish stacked up is most likely the first that is removed from the stack.

For its implementation, we'll be using a Node class:

private final class Node < T > {
     private (set) var element: T
     private (set) var nextElement: Node < T >?

     init(element: T, nextElement: Node < T >?) {
         self.element = element
         self.nextElement = nextElement

which stores:

  • an element
  • a reference to the next element in the list, or nil if it's the bottom element The idea is to create a list of nodes by linking each node to the next:

The stack itself is implemented as follows:

public struct Stack < T > {
     private var head: Node < T >?

     var isEmpty: Bool { return head == nil }

     mutating public func push(element: T) {
         let node = Node(element: element, nextElement:
         self.head = node

    mutating public func pop() -> T? {
         if let head = self.head {
                 self.head = head.nextElement
                 return head.element
         return .None

The head property always points to the last node added to the stack. When pushing an element, a new node is created, containing the element to store and the reference to the currenthead, and it is set as the new head of the stack.

The pop method instead checks if the head contains a value, in which case it removes the node from the head and then returns its element. Removing a node from the head consists of replacing the head property with the node referenced by the nextElement property of the removed node, which can be nil if there's no element left in the stack.

Using the stack is pretty simple: values are stacked up using push, and removed using pop:

var stack = Stack < Int >()


stack.pop() // Returns 30
stack.pop() // Returns 20
stack.pop() // Returns 10
stack.pop() // Returns nil - the stack is empty
Tip #5 - Representing the Lack of Value: Optionals

In Objective C, classes are reference types, which means that they are assigned and passed by reference and not by value. For instance, when a string is created we are used to writing code like:

NSString *string = @"I'm a reference type";

Since the string variable is a reference, when it is nil it means it doesn't point to any instance
- it lacks a value. So, checking if a reference points to an instance can be simply done with a logical expression like:

if (string != nil) { ... }

Similarly, to check if a variable doesn't reference any instance:

if (string == nil) { ... }

When it's about value types instead, it's a problem, because there is no special value indicating the lack of a value.

A common pattern is to label an unused value in the spectrum of all possible values - think for example at theselectedSegmentIndex property of UISegmentedControl, which by convention uses the -1 value to indicate absence of selection. Whereas this workaround may work for numbers, it doesn't for types with a restricted set of possible values (such as a boolean) or structures.

As an attempt to fix this problem, Swift introduces optionals, used to indicate the absence of value for either value and reference types.
Optionals is conceptually a very simple topic, but in reality it can be very complex if not completely understood.

One important thing to never to be forgotten, is that an optional is implemented as a generic enumeration:

enum Optional < T > {      case None      case Some(T) }

However, since optionals are frequently used, their usage is made less verbose by providing some syntactic sugar. Statements at the left side of the following table and the corresponding at the right are equivalent.

var x: Optional < Int >          var x: Int?
x = .None                             x = nil
x = .Some(10)                      x = 10
x == .None                           x == nil

It's important to remember that a variable declared as optional is of an enum type and not of the value it contains- this helps prevent several headaches caused by improper usage of optionals. When the enum holds a value, it is stored as the associated value of the .Some enum case.

Wrapping and Unwrapping

The action of storing a value into an optional variable is usually referred to as wrapping, whereas the opposite action is unwrapping. These terms help with remembering that an optional variable is not the value it contains. An optional variable can be thought as a box, which can be empty (nil = .None = absence of value) or can contain something. In order to use the "something", it must be unwrapped from the box first.

To understand this concept, let's look at a simple example. We can sum 2 Int variables:

let x: Int = 10
let y: Int = 20
let z: Int = x + y

but we cannot sum 2 optional Int variables:

let x: Int? = 10
let y: Int? = 20
let z: Int? = x + y

Value of optional type 'Int?' not unwrapped: did you mean to use '!' or '?'?
We can sum the values unwrapped from optional variables though, using either optional binding:

if let unwrappedX = x, unwrappedY = y {
     let z = unwrappedX + unwrappedY

or forced unwrapping (which is highly discouraged, except for a restricted number of cases):

let z = x! + y!

Optional Binding

The let unwrappedVar = optionalVar syntax is called optional binding when used in an if statement, and consists of:

if optionalVar contains a value:
unwrapping a value from optionalVar
assigning it to the implicitly declared unwrappedVar variable, (having the same type of the unwrapped value)
evaluating to true

otherwise, if optionalVar doesn't contain a value (i.e. it's nil):

  • evaluating to false (with the if branch skipped)

Syntactic Sugar

The syntactic sugar uses ? and ! as both operators and modifiers, depending on the context they are used in:

  • ? in variable declarations means of optional type, like in var x: Int?
  • ? in an expression means safe unwrap, and is used in optional chaining
  • ! in a variable declarations means implicitly unwrapped optional, representing an optional variable behaving like a non optional one
  • ! in expressions means forced unwrapping, and as its name suggests, is used to force the value extraction from an optional

Remember that both the ! operator and modifier are very dangerous when improperly used, because:

  • accessing an implicitly unwrapped optional when it's nil will generate a runtime exception
  • forced unwrapping an optional variable when it's nil will generate a runtime exception So they must always be used in a controlled environment, and for very specific reasons. Knowing when to use them will probably come with experience, but in case of doubt, it's always better to keep a conservative approach and avoid their usage.
Optional Chaining

The last topic covered in this quick intro to optionals is optional chaining. Consider the following structure:

struct User {      var emails: [String]? }

where the emails property is an optional array of String. If we declare an optional variable of User type:

let user: User?

and later in our code we want to retrieve the first email address, we'd need to use optional binding to extract the user first and the array later:

if let user = user {      if let emails = user.emails {          let firstEmail = emails.first          ...      } }

which is equivalent to:

if let user = user, emails = user.emails {      let firstEmail = emails.first      ... }

Using optional chaining instead, we can use the ? operator to unwrap a value from an optional (if any) - in case of anil value the expression evaluation stops and resolves to nil. Multiple unwraps can be performed in the same statement, and the expression is fully evaluated and executed if all unwraps succeed. Basing on this new knowledge, the previous code can be rewritten as:

let email = user?.emails?.first

If either user or emails is nil, the expression evaluates to nil. Otherwise the value of first is returned.
Note that optional chaining can be used for both properties and methods. For example, to add a new email address the following expression can be used:

user?.emails?.append("new email")

The append method is invoked only if the preceding expression evaluates to a non-nil value, otherwise it is skipped and nothing occurs.

Tip #6 - Tuples: Anonymous Structures

Everybody knows that in Objective C, functions and methods can return one value only, which can either be a basic data type (including enums and blocks) or an instance of a class. A function returning more than one value has to either:

  • create a class containing as many properties as the values to return, and use it as the return type
  • use a dictionary or array
  • pass references for all parameters after the first

The latter is commonly used, even in several foundation APIs, such as the error parameter in the following static method from NSData:

+ (instancetype)dataWithContentsOfURL:
(NSError **)errorPtr

Of course in Swift the same pattern can be used, and in fact the corresponding counterpart of the above method is:

     contentsOfURL aURL: NSURL,
     options mask: NSDataReadingOptions,
     error errorPtr: NSErrorPointer

Note: The case of NSError as the 2nd return value, very frequently used in almost all iOS/MacOS frameworks, can alternatively and more efficiently be implemented in swift using enumerations. See tip #7.

This case is an example of an API, which for obvious reasons we cannot change. However, when developing our own code, we have at our disposal a very useful tool allowing the creation of anonymous structures called


A tuple, which is a value type, is a list of typed values optionally named and enclosed in parentheses:

let unnamedTuple = ("Name", 34, "my@email.com")
let namedTuple = (name: "Name", age: 34, email:"my@email.com")

A function returning the min and max values from a list of temperatures can be implemented as:

func rangeOfTemperatures(temperatures:
     [Double]) -> (min: Double, max: Double) {
     return (minElement(temperatures),


  • the return type, which is a tuple (min: Double, max: Double) with 2 named parameters, min and max
  • the tuple built in the return statement is omitting names, because type inference is able to infer them from the function return type

Bonus Tip #1: Tuples in an Array

As a tuple is a value type on its own, it can be used as any other value type, including an array data type:

var arrayOfTuples: [(name: String, email: String)] = []
let el = (name: "John", email: "my@email.com")

Bonus Tip #2: The List of a Function Arguments Is a Tuple

Looking at a function declaration:

func _min(a: Int, b: Int) -> Int {
     return a < b ? a : b

the list of parameters looks like a tuple. Well, it's actually a tuple - we can invoke the _min function as either:

_min(10, 7)


let minmax = (10, 7)

Note: in order for a tuple to be passed in place of the list of a function/method parameters, the tuple itself must be immutable (i.e. declared using let and not var).

Tip #7 - Enumerations: One Return Value or Another

Consider the following Objective C method:

- (NSArray *) retrievePostsWithError:(NSError **error) {

which is supposed to return an array of posts if the call succeeds, otherwise it returns an error via the reference variable error.

For every invocation, one of the 2 return values is not used:

  • if the call succeeds, the method returns an array of posts, and error is set to nil
  • if the call fails, the method returns nil, whereas error is set to an instance of NSError So it's an "either-or" case, which can be handled in a more elegant way using Swift enumerations with associated values.

In Swift, any switch case can have one or more associated values whose types are defined in the case declaration. Note that associated values are not statically assigned to the enumeration cases, just their types are.

In our case, we need 2 cases with an array associated to the Success case and an NSError associated to theFailure case:

struct Post { /* ... */ }

enum Result {
     case Failure(NSError)
     case Success(Array < Post >)

Before diving into looking at how to use this enumeration, let's make it more generic so it can be reused for other types. The above code defines the Result enumeration to work with the Array < Post > type only, but that type can be made generic, enabling the Result enumeration to work with any type:

enum Result < T > {
     case Failure(NSError)
     case Success(T)

Unfortunately, the code as written above doesn't compile because Swift doesn't support generic associated values if there is at least another case using associated values. The solution is to box the generic value into a class:

public class Box < T > {
     public let value: T
     public init(_ value: T) { self.value = value }

and then use Box < T > as the associated type:

enum Result < T > {
     case Failure(NSError)
     case Success(Box < T >)

With this new tool in our bag, the retrievePostsWithError method can be redefined in Swift as:

func retrievePostsWithError() -> Result<[Post]> {
     /* ... */

and invoked like:

let result = retrievePostsWithError()

switch result {
case .Failure(let error):
     println("An error occurred: \(error.localizedDescription)")

case .Success(let boxedResult):
     let posts = boxedResult.value // This is an array of Post
     println("\(posts.count) posts successfully retrieved")
Tip #8 - Blocks vs. Closures

Everybody has written blocks in Objective C, and everybody has at least once wondered what's the correct syntax to use depending on the context.

The Swift counterpart of the Objective C block is the closure. A closure is an unnamed and self contained block of code which falls under the category of reference types, so it can be assigned to variables, passed to functions as argument, and so on - and of course it can also be executed.

The syntax to create a closure and assign to a variable is pretty simple:

let _min = { (a: Int, b: Int) -> Int in
     return a < b ? a : b

The closure signature is specified in the same way as in functions, and the in keyword separates the signature from the implementation. Everything is enclosed in curly braces. It can be invoked as if it were a function:

let minimum = _min(3, 5)

Although closures can be thought as a subset of functions, in reality it's the opposite: functions are a special case of closures.

The good parts about Swift closures vs. Objective C blocks is in their syntax: very clean, easy to remember, and can be optimized/simplified depending on the context. For example, omitting the input and output types when they can be inferred, and using shorthand arguments and implicit returns for single statements.

But what's probably the most useful simplification is the trailing closure syntax: when a closure is passed as the last argument of a function or method, it can be written outside of the parenthesis, and without the external parameter name (if any). For example, the well known animateWithDuration can be invoked as:

UIView.animateWithDuration(1.0, animations: {
     // Do the animation
} )

but using the trailing closure syntax it becomes:
UIView.animateWithDuration(1.0) {
     // Do the animation

Closures Can Be Stored and Executed Later

Being closures treated as any other data type, they can also be stored in a data structure to be executed at a later time and without any limit to the number of times they can be invoked.

It's relatively straightforward to implement a very simple instantiator, where using a declarative method, a type is bound to a closure which creates and returns an instance of that type.

The first step is to define an Instantiable protocol with a parameter-less initializer only, which all registrable types must implement:

public protocol Instantiable {

and a closure alias taking no parameter and returning an instance of a type implementing that protocol:

public typealias Initializer = Void -> Instantiable

The instantiator implementation would look like:

public struct Instantiator {
     private var invokers = [String : Initializer]()

     mutating func register < T: Instantiable >(type: T.Type,
     initializer: Initializer) {
         let key = self.stringFromType(type)
         self.invokers[key] = initializer

     mutating func instantiate < T: Instantiable >
     (type: T.Type) -> T? {
         let key = self.stringFromType(type)
         if let invoker = self.invokers[key] {
             return invoker() as? T
         return .None

     private func stringFromType < T >(type: T.Type) -> String {
         return "\(type)"

The register method, given a type and a closure stores the initialization closure in the invokers dictionary, using as key the string representation of the type.

The instantiate method instead, given a type, retrieves the corresponding initialization closure from the dictionary (if found) and invokes it; otherwise, it returns .None (which is equivalent to saying nil).

Some use cases:

// Create extensions of a few types, adopting the
Instantiable protocol
extension Int : Instantiable {}
extension Array: Instantiable {}
extension UIView: Instantiable {}

// Create the instantiator
var instantiator = Instantiator()

// Register types
instantiator.register(Int.self) { Int() }
instantiator.register([String].self) { [String]() }
instantiator.register(UIView.self) { UIView() }

// Instantiate types
let int = instantiator.instantiate(Int.self)
let array = instantiator.instantiate([String].self)
let view = instantiator.instantiate(UIView.self)

This simple example binds a type to a closure creating an instance of the same type - however, it can be extended to work similarly to a dependency injection container, with a protocol used as key, bound to a class implementing it.

Tip #9 - Flexible Multi-Value Selection Control: TheSwitch Statement

When the execution flow has to go through one of multiple paths depending on a value, Objective C's switchstatement comes into help:

UIDeviceOrientation orientation = [[UIDevice currentDevice]

switch (orientation) {
     case UIDeviceOrientationLandscapeLeft:
     case UIDeviceOrientationLandscapeRight:

The biggest limitation is that it works with ordinal types only (integer, unsigned integer, boolean, enumerations, etc.) - other types (strings, double, strings, classes, etc.) are not supported. In those cases a multiple if/else if statement must be used:

double radius = 3.23;

if (radius == 3.14) {
} else if (radius == 6.28) {
} else {

Fortunately, in Swift the switch statement has been supercharged. It can be used with almost any type, including strings, floating point numbers, reference types, and so forth. But there's a lot more.

First of all, there are some differences that are often seen as limitations compared to the Objective C counterpart:

There is no implicit fall through. In Objective C, if a case doesn't end with a break statement, execution continues to the next case's body. In Swift instead the break statement is always implicit.

The cases list must be exhaustive: any possible value must be handled by at least one case As described in tip tip #7 , an enumeration can have associated values to one or more of its cases. For instance, the optional enumeration:

enum Optional < T > {
     case None
     case Some(T)

has an associated value of generic type T bound to the Some case. Associated values can be easily extracted from a case using a switch statement:

let integer: Int? = 10

switch integer {
case .None:
     println("It's nil")

case .Some(let value):
     println("It has a value: \(value)")

It also works with cases handling multiple values, ranges, tuples and conditions:

let point = (x: arc4random() % 10, y: arc4random() % 10)

switch point {
case (0, 0):
     // Matches the (0,0) point
     println("Single match")

case (0, 1), (0, 2), (4, 6):
     // Matches any of the values in the list
     println("Multiple matches")

case (0...5, 0):
     // Matches any value having (y = 0) and (0 <= x <= 5)
     println("Interval match")

case (4, _):
     // Matches any value having (x = 4)
     println("Single value match")

case (5, let y):
     // Matches any value having (x = 5), but capturing
     the value of y
     println("Single value watch with y = \(y)")

case let (x, y) where x == y:
     // Matches any value having (x = y)
     println("Value binding with condition")

case (let x, let y) where x == y:
     // Equivalent to the previous case
     println("Value binding with condition")

Tip #10 - Objective C and Swift in the Same Project

Apple put in a lot of effort to make the 2 languages work together. It's a must have when a very strongly typed language like Swift meets a not-so-much strongly typed like Objective C and a large number of frameworks entirely written using it.

To date no framework is implemented, either partially or fully using the Swift language. Including new ones, like the ResearchKit Framework , which is 100% Objective C and whose development started after Swift was released. Apparently there's a limitation in the language that prevents it from being used for system frameworks, but this is likely going to change in the future.

Below are some Q&A's about using Objective C and Swift:

Question #1
Can I use Swift in an Objective C project?

Yes. Create or add a new Swift file to the project, and it will compile without any problem.

Question #2
How do I access Objective C code from Swift?

When the first Swift file is added to or created in an Objective C project, Xcode will prompt to create abridging header

which is merely a header file, initially empty, but with a special function: all #imports will automatically be bridged to Swift.

So if we have an Objective C ViewController class, defined in the ViewController.h header file, simply adding the #include statement to the bridging header the class (and whatever is defined in that header) will automatically be accessible from Swift: #include "ViewController.h"

Question #3
How do I access Swift code from Objective C?

Xcode automatically creates Objective C wrappers for compatible Swift code, stored in the < project-name >-Swift.h, where < project-name > is the actual project (module) name. To access Swift types from Objective C, simply import the mentioned header file: #import "< project-name >-Swift.h"

Note: the Swift header is not listed in the project navigator, but it can be opened by cmd+clicking its name in an import statement. Since it is automatically generated, any change made to the file will be lost at the next compilation.

Question #4
Is there any Swift code that is not compatible with Objective C?

Yes, several Swift features are not compatible with Objective C. A non exhaustive list includes:

  • structures
  • generics
  • tuples
  • enumerations using associated values, non integer raw values, or generics
  • curried functions
  • global functions and variables

Question #5
I'm trying to use Swift code in an Objective C project. I'm importing the Swift header file, but the following error is reported by the compiler:
"< project-name >-Swift.h" file not found
Why is that happening?

Most likely there is a circular reference, which happens when an Objective header file is imported in the bridging header, and either the header file itself or its implementation imports the Swift header. For example:
#import "Test-Swift.h"
@interface ViewController : UIViewController

#import "ViewController.h"

The ViewController class is exposed to Swift, because its header is included in the bridging header, but the Swift header is also imported in its header file, causing a circular reference. To prevent circular references, it might be useful to know that:
Objective C code should not be exposed to Swift if it depends on other Swift code classes that must be exposed to Objective C, and depend from Objective C code, should not be implemented in Swift

This tutorial was made in collaboration with TopTal.