Sean Dougherty

Swift

This year was a big year for developers on Apple’s platforms. Apple announced a ton of great stuff at WWDC. The most exciting news was their announcement of a new programming language, Swift.

According to Apple’s free to download book The Swift Programming Language

“Swift is a new programming language for iOS and OS X apps that builds on the best of C and Objective-C, without the constraints of C compatibility. Swift adopts safe programming patterns and adds modern features to make programming easier, more flexible, and more fun.”

Swift is intended to be a near complete replacement for Objective-C, the language iOS and OS X apps are currently written in. While most of us love programming in Objective-C we realize that it has some rough edges. Objective-C has been around for decades and does not have a lot of the features and syntax more modern languages have introduced. Swift brings a host of modern features such as generics, tuples, closures, pattern matching and type inference while remaining safe and most importantly, fast. Swift is compact and expressive which will lead to apps requiring less code and being easier to maintain.

I predict that Swift’s approachable and familiar syntax will lead to an influx of new Cocoa and Cocoa Touch developers. These new developers will bring new ideas to the platform. I can’t wait to see what will happen over the next few years. We are going to move in directions we haven’t yet conceived of. Its an exciting time to develop for iOS and OS X. As Mattt Thompson put it “How neat that we’re all beginners at the same time though, right?”

Getting Started

Swift requires Xcode 6 beta which at the time of this writing is pre-release software. In order to download it you’ll need to be a member of the iOS Developer Program or Mac Developer Program.

Once you have Xcode 6 beta or later up and running you can start writing and compiling Swift.

In an actual application deployed to iOS devices or a Mac Swift files have a .swift extension. They can be compiled along side Objective-C, C and Objective-C++ code. Objective-C code can use Swift classes (with some restrictions) and vice-a-versa.

When conceiving Swift the authors at Apple had a goal of making learning Swift and trying out the language as easy, interactive and fun as possible. They named what they came up with Playgrounds.

Playgrounds

Playgrounds are files with a .playground extension. When opened in XCode 6 they launch an interactive environment for you to experiment with Swift code. Playgrounds are the quickest and easiest way to start writing Swift. They are a bit like Ruby’s irb but much more powerful. Results are displayed immediately in a column on the right and through a powerful feature available in other areas of Xcode you are able to visualize several sophisticated types. It is even possible to see the results of values changing in your Swift code over time. There really is no way to do playgrounds justice here. You have to interact with one to understand how awesome they are.

In fact, Apple has created a playground called “GuidedTour.playground” which is a comprehensive and interactive playground that goes through most of Swift’s language features with descriptions and live examples that you can play with and modify on the fly. The iOS Developer Library has a Swift Tour (you’ll need a valid Apple developer account to access it). Click on Swift.playground.zip to download a zip archive containing a playground file with all the code in this post.

Basics

Everyone is a first class citizen in Swift

Strings, integers, doubles, classes, structs, enums and even functions are all valid types. Gone are the distinctions between primitives and objects. All types can be stored in collections and extended. The first classifying of all types provides a concise and uniform approach to developing in Swift.

Variables

Swift is able to infer type information in most cases so specifying it is not required if a value is assigned by the expression.

1
2
3
4
5
6
7
8
9
10
11
12
13
// Swift knows this is a string because the right hand value is a string
var name = "Walter"

// variable and constant types are specified after the name and a colon
var lastName : String = "White"

var age = 1 // inferred to Int

var explictAge : Int = 1 // explicitly set to Int

var count = 1.0 // inferred to Double

var explicitCount : Double = 1 // force to an int

Constants

The Swift documentation favors immutability so constants are highly visible in the language. Constants are indicated using the let keyword in place of var.

1
2
3
4
5
6
7
let immutableName = "Walter" // an immutable string constant

// immutableName = "Walter White" // won't compile

var mutableName = "walter" // a mutable string variable

mutableName = "Walter White" // works

String

Strings are concatenated with the + operator. They can be added to with the += operator. Strings can also interpolate other calculated values using a backslash followed by the expression in parenthesis \(expression).

1
2
3
4
5
var nameDescription = "Walter"
nameDescription += " White" // name = "Walter White"

let yearsOld = 50
nameDescription += " is \(yearsOld) years old" // name = "Walter White is 50 years old"

Collections

Swift has several collection types. The most common are Array and Dictionary. Just like strings and the number types they are mutable if they are variables and immutable when they are constants.

Array

Arrays are typed in Swift.

1
2
var integers : Int[] = [1, 2, 3]
integers += "non integer" // will not compile

If the type can be inferred the type information is not required at declaration time.

1
2
3
4
5
var characters = ["Jesse", "Walter", "Hank"] // inferred as an array of strings

characters += "Skyler" // add a string to the array

characters[2] // "Hank"

Dictionary

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var states : Dictionary<String, Int> = [
    "Colorado" : 5000000,
    "Hawaii" : 1000000
]

var shows = [
    "Walter" : "Science Teacher",
    "Jesse" : "Unemployed",
    "Hank" : "DEA Agent"
] // type inferred to a key type String and value type String

shows["Jesse"] // "Unemployed"

shows["Skyler"] = "Accountant" // add an element to the dictionary

Control Flow

Swift has most of the familiar mechanisms for controlling flow that Objective-C developers are familiar with. They’re just a lot cooler and more useful in Swift.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var registered = true

if registered {
    // if statements do not require parenthesis
    // but they do require curly braces
}

// Swift has range types that are enumerable
for number in 5...10 {
    println("\(number) plus \(number) is \(number + number)")
}

let breakingBadCharacters = ["Jesse", "Walter", "Hank"]

for character in breakingBadCharacters {
    println("\(character)")
}

// a string's characters are enumerable
for letter in "Breaking Bad" {
    println(letter)
    letter
}

var funds = 0
while funds < 10 {
    // cook meth until broke is false
    funds++
}

do {
    // cook meth at least once
    funds++
} while funds < 100

Dictionaries are enumerable as a key value tuple pair. More on tuples below.

1
2
3
4
5
6
7
8
9
let cast = [
    "Walter" : "Science Teacher",
    "Jesse" : "Unemployed",
    "Hank" : "DEA Agent"
]

for (name, profession) in cast {
    "\(name) is a \(profession)"
}

Switch

The coolest and most powerful control flow mechanism in Swift is the switch statement. Swift’s switch statement works with any type compared to Objective-C’s integer only switching. Swift switch allows for pattern matching, a powerful feature new to iOS and OS X development.

Switch statements must be exhaustive so a default is required if the case statements don’t handle all possible cases. Execution does not fall through case statements so no break keyword is necessary.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let fullName = "Walter White"
var output = ""

switch fullName {
case let x where countElements(fullName) > 3:
    output = "more than 3 characters long"
case "Jesse", "Hank":
    output = fullName
case let x where x.hasSuffix("White"):
    output = "ends in White"
default:
    output = "no matches found"
}
output // "more than 3 characters long"

Functions

Functions are types just like everything else in Swift. You can define them, call them, as well as pass them as arguments to another function and return them from other functions. Functions are defined using the func keyword. They accept 0 or more arguments and may return a value. A function returns a value with a -> and type after the parentheses.

1
2
3
4
5
6
7
func add(a:Int, b:Int) -> Int {
    return a + b;
}

let sum = add(5,7)

sum // 12

In order to remain compatible with Cocoa and Cocoa Touch function arguments can have an external name as well as an internal variable name. Lets look at a UITableViewDataSource protocol method in both Objective-C and Swift.

1
2
3
4
5
6
7
8
9
10
// Objective-C
- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath;

// Swift
// notice that the first argument does not have an external name
// while the second argument is named cellForRowAtIndexPath externally
// and indexPath internally
func tableView(tableView: UITableView!,
    cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!

The Cool New Hotness

The language features below are either completely new compared to Objective-C or they work in ways novel enough to note here.

Optionals

As I mentioned above, Swift is designed to be safe. Optionals help keep code safe by forcing the developer to be explicit about variables and constants. By default all variables and constants must have an assigned value. This ensures that it is safe to use variables and constants without first checking to see if they have a value. However, sometimes we’ll need optional value variables or constants. This is where Swift Optionals come in. Optionals are a formal language feature that marks a variable or constant as potentially having no value. To mark a variable or constant as optional use a ? after the type.

1
2
3
4
5
var content:String?

func isDone() -> Bool? { return nil }

func storeUserInfo(name:String?, age:Int?) {}

When using an optional variable or function with an optional return value we must explicitly unwrap the value held by the optional using a ! after the referenced optional.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
content = "Some content here"

content // compile error

println(content!) // compiles but may introduce a run time crash if content is nil

if content {
    println(content!) // safe because optionals are true if they have a value
}

// automatic unwrapping with if let shorthand
if let safeContent = content {
    safeContent // preferred handling of optionals
}

Tuples

Tuples are a group of compound values. To create a tuple enclose multiple values in parentheses. They can contain any number of values as well as any combination of types. The values can have names or not. Tuples are the mechanism for returning more than one value from a function. Access values in a tuple by position or name.

1
2
3
4
5
6
7
8
9
10
11
12
13
var ages = (10, 15, 20)

ages.1 // 15

func getNames() -> (tom:String, dick:String, harry:String) {
    return ("Tom", "Dick", "Harry")
}

let (tom, dick, harry) = getNames()

harry // "Harry"

getNames().dick // "Dick"

Enums

Enums are useful for storing a known list of enumerable values. Swift enums support functions as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
enum Framework {
    case CocoaTouch, Rails, Android
    func language() -> String {
        switch self {
        case .CocoaTouch:
            return "Swift"
        case .Rails:
            return "Ruby"
        case .Android:
            return "Java"
        }
    }
}
let rails = Framework.Rails
let railsLanguage = rails.language() // "Ruby"

Structs

Structs are similar to classes in Swift with the distinction that they are immutable by default. They are copied when passed in code. Classes are passed by reference.

1
2
3
4
5
6
7
8
9
10
11
struct Programmer {
    var name : String
    var framework : Framework

    func frameworkLanguage() -> String {
        return framework.language()
    }
}

let cocoaProgrammer = Programmer(name:"Sean", framework:.CocoaTouch)
let frameworkLanguage = cocoaProgrammer.frameworkLanguage()

Generics

Generics are a powerful tool for code reuse. They abstract code and provide flexibility while maintaing compile time type safety. Under the hood Swift uses generics for a host of the standard library features including collections like Array and Dictionary.

The Swift Programming Language has a great example of generics. The example is a simple Stack. In order to make the stack work with with any type generics are used. The stack is type safe but flexible enough to hold any type.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct Stack<T> {
    var items = T[]()

    mutating func push(item: T) {
        items.append(item)
    }

    mutating func pop() -> T {
        return items.removeLast()
    }
}

var stackOfStrings = Stack<String>()
stackOfStrings.push("uno")
stackOfStrings.push("dos")
stackOfStrings.push("tres")
stackOfStrings.push("cuatro")
// the stack now contains 4 strings

stackOfStrings.push(123) // won't compile because 123 is not a String

Extensions

Extensions allow you to add functionality to existing types. They are similar to Objective-C’s categories and Ruby’s Modules. Unlike an Objective-C category a Swift Extension can extend classes, structures and enums. Extensions can also add computed properties and add protocal conformance to an existing type. Extensions are available app wide at compile time.

1
2
3
4
5
6
7
extension Double {
    func multiply(b:Double) -> Double {
        return self * b
    }
}

5.5.multiply(3) // 16.5

Protocols

Swift Protocols are similar to protocols in Objective-C but like their Extension counterparts they available on all types. Protocols are similiar to Java’s Interfaces. When a type adopts a protocol it is conforming to a contract defined by the protocol. Protocols define optional or required functions and/or properties. The best new feature of protocols in Swift are protocol instance properties. Protocols do not define the implementation of their functions or properties, concrete types conforming to the protocol implement all required functions and properties.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
protocol HighFiveable {
    var numberOfHighFives: Int { get }

    func highFive()
}

class Person: HighFiveable {
    var numberOfHighFives = 20

    func highFive() {
        println("I was high fived!")
    }
}

let jim = Person()

jim.highFive() // "I was high fived!"

Summary

I’ve included all of the code snippets above in a playground file you can download and open up in Xcode 6 beta or greater.

Swift.playground.zip

This is just a brief look at some of the key language featuers of Apple’s new programming language, Swift. Reach me on Twitter @sdougherty if you find any errors or have anything to add.