Teaching App Development with Swift

Leave a comment

Source: https://swifteducation.github.io/teaching_app_development_with_swift/

Teaching App Development with Swift

Teach Students How to Create iOS Apps

Engage students with a project-based curriculum, and guide students in creating iOS apps. Adopt projects and lesson plans to fit your course and different learning styles. Create real apps that teach students Swift, the iOS SDK, and the Apple developer toolset.

Download Download the Course Materials (~90MB)

GitHub Octocat Report Issues and Contribute on GitHub

Speech Bubble Ask Questions and Share Techniques in the Education Forum

General Materials

Creative students love hands-on learning. Projects lead the lessons, so you can guide and facilitate learning, supporting student work with technical understanding.

Projects and Lesson Plans

Guide students through each level of projects, which provide a progressive framework for learning. Let the app features lead to technical discovery and stimulate student creativity. Select projects and lessons to fit your course requirements and student experience.

Level 1: Xcode Fundamentals and Swift

Level 2: Single View Applications and MVC

Level 3: Frameworks and APIs

Level 4: Navigation, Tab Bar and Table View Controllers

The course materials only, and not any other content of this web page, are to be used pursuant to a Creative Commons license, as specified in the license information within the course materials.

Trademark Information

The Swift logo, Apple, the Apple logo and other Apple trademarks, service marks, graphics, and logos used in connection with the Swift Education project are trademarks or registered trademarks of Apple Inc. in the US and/or other countries. Other trademarks, service marks, graphics, and logos used in connection with the Swift Education project may be the trademarks of their respective owners. You are granted no right or license in any of the aforesaid trademarks, and further agree that you shall not remove, obscure, or alter any proprietary notices (including trademark and copyright notices) that may be affixed to or contained within the Service.

For further information about proper referential uses of the Swift logo, please review the “Guidelines for Using Apple Trademarks and Copyrights”.

Why I want Swift to be your first language

Leave a comment

Source: http://www.aaronblock.com/thoughts/2015/8/21/why-i-want-swift-to-be-your-first-language

In preparation for an upper level class that I’m teaching this semester, I spent the summer writing my first app entirely in Swift. (It’s 7 Second Diet, a meal-tracking app that’s not a pain in the tuchus to use.) After spending some quality time with Swift, I realized how much I want to use Swift to teach introduction to computer science.

Choosing a language

Introduction to computer science is a unique class because most students that enroll in it don’t know if they like computer science or not. As a result, a good intro class does two things: it teaches students the fundamentals of computer science and helps students learn to love computer science. Many of our department’s best majors originally took intro to get their quantitate credit and never left because it was their favorite class. So, when choosing a language for intro, it’s important to pick a one that will:

  • Be intricate enough to cover the core computer science concepts
  • Be robust enough that students can use it for years worth of assignments
  • Be easy enough that students can start programming within one week
  • Be powerful enough that students can make real applications by the end of the first semester

Why Swift

Currently, most departments teach intro in C, C++, Python, or Java. Java is probably the most popular and Python is probably the second most popular. (Our primary language is Java, but we teach some intro classes in Python.) A few other schools will use languages like JavaScript, C#, Smalltalk, Haskell, or Lisp. Every language has its pros can cons and rather than giving you a giant spreadsheet of how each language stacks against Swift, I want to give you a few examples of where Swift really shines in an intro class.


One trait that Python and Swift both share is that on the first day of class I can type:

print("Hello World")

and everyone in the class immediately understands this code. In Java, when I type:

package playground;
public class Starter {
    public static void main(String[] args) {
        System.out.println("Hello World");

everyone’s eyes glaze over and they think to themselves “what in the hell is going on here?” With Java, C, and C++, you have to spend the first month of class telling students “ignore this” because even simple programs have a lot of syntax overhead. This wastes time and causes some students to discount computer science because “it makes no sense.”


This is a moment that will happen sometime in the next two weeks. A student will wave me over to her computer with a question about how to fix her broken Java code. When I get to her computer, I’ll immediately point to a line of code and state “You are missing a semicolon here.” The student then swears, “I worked on this for a F!CKING HOUR.” I commiserate and then turn to her neighbor who has exactly the same issue (but he’s been working on it for TWO hours). It’s fun to look like a technopath, but both students wasted their time on silly mistakes. For experts, missing a semicolon is annoying. For intro students, that’s their Japanesse assignment. Swift still has syntax the students will need to know, but they’ve dramatically reduced the amount of “useless” syntax that can trip up students.


Possibly my favorite thing in Swift is “optional types.” For those who haven’t worked with Swift, an optional type is exactly the same as a normal type, except it can have the additional value of nil, which represents “no value.” I love optional types because they allow me to write algorithms that behave correctly but occasionally don’t return a value. For example, suppose you wanted to find the smallest number in a list of integers. If the list is empty, what value should you return? Should you return 0? Should you throw an exception? Should you return MAX_INT? None of those are correct. Optionals let the students write the algorithm as intended: if the list is empty, return nil.


Many professors who teach Java like teaching “objects first.” The idea behind “objects first” is that students should learn object-oriented programming first and learn algorithmic reasoning second. I do not like “objects first.” Explaining why I don’t like “objects first” is a post unto itself. So, I’m going to brief here: object-oriented programming is a tool in algorithmic reasoning. It’s better to learn algorithmic reasons first so you can understand why object-oriented programming is necessary.

“Objects first” is a popular technique for teaching Java because (almost) everything in Java is an object. So, to do anything interesting in Java either you have to teach “objects first” or you have to give students a library to hide the object-oriented programming until later in the semester. Either way is messy.

On the other hand, object-oriented programming is a core concept in computer science and needs to be taught to students in their first semester. So any language that doesn’t use object-oriented programming (e.g., C) is a bad choice for an intro language.

Because code can live inside or outside of classes in Python, Swift, and C++, these languages making teaching introduction to computer science a lot less messy.


Most intro students understand the basics of algorithmic reasoning before they enroll. Where they have difficulty is formalizing an algorithm so that it can run on a computer. The technique I teach them is to write an English description of what you want to happen and then transform it into code where your nouns are represented by variables and verbs are represented by functions. Named parameters make this tranformation cleaner because they allow functions to be more verbose. If you haven’t used named parameters before, the easiest way to explain them is to see an example.

Suppose that you wrote a function that took two lists of integers as parameters and returned the smallest element in the first list of integers that wasn’t included in the second list. Without named parameters, you would call the method like so:

x = findSmallestElementNotIn([20,30,55,22,11,34], [100,23,45,11,20,-4])

With named parameters you would write:

x = findSmallestElement(in: [20,30,55,22,11,34], notIn: [100,23,45,11,20,-4])

The named parameters are the “in:” and “notIn:” included with the parameters. If you had more parameters, then each would have a name as well. By including names with each parameter, the code clearly reads like a sentence:

“Set x to be the smallest element in the list [20,30,55,22,11,34] that is not in [100,23,45,11,20,-4]

Named parameters make the transformation from English to code much easier. Also, when combined with an IDE that has good autocomplete functionality, students can write better code faster.


If you know a C programmer and you ask her about Java programmers fresh out of college, then you will hear the following sentence:

“Ugh, kids today just don’t understand how memory is managed. I asked him to write malloc and he looked at me like I was speaking Greek.”

Possibly the biggest problem with Java and Python as first languages is that they obscure memory management. For the types of programs you write in intro, this isn’t bad. However, once you start writing larger programs that need good memory performance it becomes important.

For those who haven’t used Java or Python before, those two languages are at one end of the “memory management continuum.” In these languages, you never explicitly delete a memory reference. Java and Python run “garbage collection” routines that remove memory when they are no longer necessary. On the other end, C and C++ require developers to explicitly destroy memory allocations. Swift uses a technique calledAutomatic Reference Counting (ARC) that lives in the middle. Under ARC, developers do not explicitly destroy objects but instead must correctly organize their memory references and classify them as “strong,” “weak,” or “unowned” so that they can be automatically destroyed without needing to run an additional memory management process. While ARC doesn’t require developers to directly manage memory, it helps students learn how to organize memory and think about how objects are stored in memory without harassing them about the details. (Students should still learn explicit memory management, just not in their first year.)

Where Swift could improve.

With Swift 2.0 coming out soon, most of my complaints about Swift are going away. That being said my biggest complaint about Swift is that it lacks Python’s simple input() and read() commands. (If you haven’t use Python before: input() prompts the user for an input and returns a string, and read() will take the contents from a file and return it as a string.) Having access to simple user/file input dramatically expands the set of examples and assignments I can present in the first month of intro. I can work around this by providing students with a library that would include my implementation of these two methods. The downside is that now I’m teaching the students my code and not a technique they can apply outside of the classroom. While this would work, it isn’t ideal.

Why don’t I use Swift this year?

Even though I think Swift is ideally suited for intro, for the next year at least, I’ll be using Java in my classes. Why?

  1. The AP test is in Java. This is the biggest reason. Each year we have several students who took high school computer science, got a 4 or 5 on the AP, and want to skip the first semester. We want to make sure they can do that without taking summer school. Because we want students to have the same language for their entire first year, if we use Swift, then those students can’t skip the first semester.
  2. Language in flux. Given how much change has happened in Swift during the past year, I’m hesitant to teach intro students how to program in a language that could have changing syntax.
  3. No Windows IDE, yet. The fact that Swift is now open source is wonderful. I look forward to the day when we have great a IDE on Windows. That isn’t the case right now. While we have Macs in our labs, students like working at home and they don’t all have Apple laptops. Even if some projects have to be built on lab computers, we’d like to be as flexible as possible.
  4. This isn’t a a decision I can make by myself. Every class in computer science builds off of the last class. So, if we change our introlanguage, then nearly every other class in our department will need to change as well. Just because I’m excited about Swift for intro doesn’t mean it’s the best decision for our department. Every year we revaluate how we teach and how we can better serve our students. I expect that this year we’ll have a lot of great discussions about the pros and cons of Swift, Java, and Python.


I could go on describing the advantages of Swift and Xcode in an intro class for a long time (the ease of use Interface Builder, the use of let make constants a first class principal…) but this has gone on long enough. Ultimately, I want to use Swift as the language in introduction to computer science because it allows me to teach all the key concept I want to teach; it is easy enough that students can start using it on day one; it’s sufficiently strict that it keeps students in line so they won’t make (as many) stupid mistakes; and it’s powerful enough that students can use it for the next decade without a problem. While I’m not going to teach introduction to computer science with Swift right now, I am ecstatic about the future of Swift and the impact it will have on future computer scientists.

Aaron Block is an assistant professor of computer science at Austin College. In another lifetime, he was a program manager at Microsoft.

Introduction to Swift Programming and Computer Science – This app works on Windows 8 and Windows 10

Leave a comment

Source: https://www.microsoft.com/en-us/store/apps/introduction-to-swift-programming-and-computer-science/9wzdncrdhq4t

The Swift Programming Language – A Free book from Apple

Leave a comment

Source: https://itunes.apple.com/us/book/the-swift-programming-language/id881256329?mt=11

This book is available for download with iBooks on your Mac or iOS device, and with iTunes on your computer. Books can be read with iBooks on your Mac or iOS device.


Swift is a new programming language for creating iOS and OS X apps. Swift 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’s clean slate, backed by the mature and much-loved Cocoa and Cocoa Touch frameworks, is an opportunity to reimagine how software development works.

This book provides:
– A tour of the language.
– A detailed guide delving into each language feature.
– A formal reference for the language.

Apple’s new Swift language explained: A clever move to boost iOS, while holding Android apps back

Leave a comment

Source: http://www.extremetech.com/computing/183563-apples-new-swift-language-explained-a-clever-move-to-boost-ios-while-holding-android-apps-back

While Apple’s WWDC keynote yesterday was full of exciting new changes and features, one piece of news caught everyone off guard: With iOS 8 and OS X 10.10, and the the latest version of the Xcode developer tools, Apple has introduced a whole new programming language called Swift. According to Apple, Swift will make it a lot easier and more fun to develop apps for both iOS and OS X — in contrast to the current language, Objective-C, which has been likened by esteemed programmers to pulling teeth. Swift will also apparently bring a significant performance boost over Objective-C programs.

While Apple is being fairly coy about the exact reasoning behind the launch of Swift, it’s probably to reel in more developers, who will then create more apps, ensuring the continued dominance of iOS app ecosystem. But hey, we’re getting ahead of ourselves: What is the Swift programming language, anyway? And how can switching to a new programming language provide a massive 50% performance boost over a language that is already considered to be pretty fast?

What is Swift?

A small example of Swift code

For a start, the Swift language bears no relation to the Swift (A6) CPU architecture or the existing Swift parallel scripting language. Obviously, when Apple decides on a name for a product, it doesn’t let existing products or trademarks get in the way.

In the words of Apple, Swift is like “Objective-C without the C.” The introduction to Swift on the Apple developer website outlines Swift as safe, concise, and interactive (your code is interpreted and rendered in a live “Playground” view in the Xcode IDE).

In this context, “safe” mostly refers to the fact that the language is type safe — but thanks totype inference, type declarations are less onerous, making Swift more concise than C or Objective-C. The Switch statement is also is also safer and easier to use than the C counterpart. The two-phase initialization process for classes, slightly tweaked from the Objective-C way of doing things, also improves safety. Along with type inference, Swift also introduces very concise closures (lambdas).

A larger Swift source code sample.

On the compilation and runtime side of things, Swift targets the same Cocoa (OS X) and Cocoa Touch (iOS) APIs, and uses the same LLVM as Objective-C. Swift code can co-exist with Objective-C code in the same project, encouraging adoption.

A deep analysis of Swift is beyond the scope of this story, but in general it shares a lot of similarities with other modern languages, such as Rust, with a lot of popular ideas and patterns that have been assimilated from other languages. There will be a lot of cries that Apple copied/imitated/ripped off other languages — but ignore them. When it comes to programming languages, this kind of imitation and embrace-and-extent evolution is the norm, and a sign that everything is working as intended.

For programmers and the otherwise technically inclined, Apple has published a free 500-page Swift Programming Language book if you want to learn more about the language. You’ll need an Apple Developer account (free) to download the beta of Xcode 6, which fully supports Swift.

Swift performance, compared to Python and Objective-C

Will Swift apps be faster than Objective-C apps?

On stage at WWDC, Apple’s Craig Federighi showed some interesting graphs that appeared to show a huge 40-50% performance lead for Swift over Objective-C. He did not say that apps written in Swift would be faster than Objective-C, though. And he was very picky about which benchmarks he showed. In reality, Swift is very unlikely to be significantly faster than Objective-C. They are both statically typed, compiled languages — using the same LLVM compiler, no less. To obtain such a graph, Apple probably had to choose an Objective-C feature that is known to be slow/buggy — or intentionally optimize a Swift feature, purely for the sake of producing a pretty graph.

We look forward to doing some real benchmarking in the coming weeks and months, though, as Swift apps start pop up on the App Store.

Why did Apple release Swift?

It all boils down to this question. Why, with a huge pool of developers who are already very knowledgeable in the ways (and quirks) of Objective-C, is Apple releasing a new programming language? Doesn’t the world already have enough programming languages? Why didn’t Apple choose another modern language, like Rust or Go?

There are a variety of possible answers, depending on how cynical you are. The nicest explanation is that Objective-C is a horrible language to learn — and so the introduction of Swift will massively increase the number of developers who are happy and willing to develop iOS and OS X apps. (The counterpoint to this is that we may then see a lot more junk apps in the App Store.)

The cynical explanation is that Apple wants to use its heft to weaken the Android app ecosystem. Thanks to their shared support for C, and tools to port Objective-C to Java, it’s currently fairly easy to port an app from iOS to Android. Porting Swift apps to Android, on the other hand, would be a lot more time consuming.A more complete explanation is that Objective-C is an old language — it just had its 30th birthday — and so it does make sense to introduce a newer language that more closely conforms to the modern methods of app development. As a corollary to this, Apple is the creator and curator of Swift, meaning it has a lot more flexibility to add and change functions as time goes by, rather than being forever shackled by the Objective-C framework. Think of it as an investment in the future.

In reality, it’s probably a mix of all three reasons. Ultimately, there are a lot of good reasons for creating your own, tailor-made programming language. The difficult bit is in getting people to use and embrace the new language. Apple, with its captive army of millions of developers, certainly won’t have that problem.

Learn the Essentials of Swift

Leave a comment


Start Developing iOS Apps (Swift)

On This Page

Learn the Essentials of Swift

Your first lesson is presented in the form of a guided Swift playground, a type of file that lets you change and interact with the code directly in Xcode and see the result immediately. Playgrounds are great for learning and experimenting, and this one helps get you up to speed on fundamental Swift concepts.

Learning Objectives

At the end of the lesson, you’ll be able to:

  • Differentiate between a constant and a variable

  • Know when to use implicit and when to use explicit type declarations

  • Understand the advantage of using optionals and optional binding

  • Differentiate between optionals and implicitly unwrapped optionals

  • Understand the purpose of conditional statements and loops

  • Use switch statements for conditional branching beyond a binary condition

  • Use where clauses to impose additional constraints in conditional statements

  • Differentiate between functions, methods, and initializers

  • Differentiate between classes, structures, and enumerations

  • Understand syntax for (and basic concepts behind) inheritance and protocol conformance

  • Determine implicit types and find additional information using Xcode’s quick help shortcut (Option-click)

  • Import and use UIKit

Basic Types

A constant is a value that stays the same after it’s declared the first time, while a variable is a value that can change. A constant is referred to as immutable, meaning that it can’t be changed, and a variable is mutable. If you know that a value won’t need to be changed in your code, declare it as a constant instead of a variable.

Use let to make a constant and var to make a variable.

  1. var myVariable = 42
  2. myVariable = 50
  3. let myConstant = 42

Every constant and variable in Swift has a type, but you don’t always have to write the type explicitly. Providing a value when you create a constant or variable lets the compiler infer its type. In the example above, the compiler infers that myVariable is an integer because its initial value is an integer. This is called type inference. Once a constant or variable has a type, that type can’t be changed.

If the initial value doesn’t provide enough information (or if there is no initial value), specify the type by writing it after the variable, separated by a colon.

  1. let implicitInteger = 70
  2. let implicitDouble = 70.0
  3. let explicitDouble: Double = 70

Values are never implicitly converted to another type. If you need to convert a value to a different type, explicitly make an instance of the desired type. Here, you convert an Int to a String.

  1. let label = "The width is "
  2. let width = 94
  3. let widthLabel = label + String(width)

There’s an even simpler way to include values in strings: Write the value in parentheses, and write a backslash (\) before the parentheses. This is known as string interpolation.

  1. let apples = 3
  2. let oranges = 5
  3. let appleSummary = "I have \(apples) apples."
  4. let fruitSummary = "I have \(apples + oranges) pieces of fruit."

Use optionals to work with values that might be missing. An optional value either contains a value or containsnil (no value) to indicate that a value is missing. Write a question mark (?) after the type of a value to mark the value as optional.

  1. let optionalInt: Int? = 9

To get the underlying type from an optional, you unwrap it. You’ll learn unwrapping optionals later, but the most straightforward way to do it involves the force unwrap operator (!). Only use the unwrap operator if you’re sure the underlying value isn’t nil.

  1. let actualInt: Int = optionalInt!

Optionals are pervasive in Swift, and are very useful for many situations where a value may or may not be present. They’re especially useful for attempted type conversions.

  1. var myString = "7"
  2. var possibleInt = Int(myString)
  3. print(possibleInt)

In this code, the value of possibleInt is 7, because myString contains the value of an integer. But if you change myString to be something that can’t be converted to an integer, possibleInt becomes nil.

  1. myString = "banana"
  2. possibleInt = Int(myString)
  3. print(possibleInt)

An array is a data type that keeps track of an ordered collection of items. Create arrays using brackets ([]), and access their elements by writing the index in brackets. Arrays start at index 0.

  1. var ratingList = ["Poor", "Fine", "Good", "Excellent"]
  2. ratingList[1] = "OK"
  3. ratingList

To create an empty array, use the initializer syntax. You’ll learn more about initializers in a little while.

  1. // Creates an empty array.
  2. let emptyArray = [String]()

You’ll notice that the code above has a comment. A comment is a piece of text in a source code file that doesn’t get compiled as part of the program but provides context or useful information about individual pieces of code. A single-line comment appears after two slashes (//) and a multiline comment appears between a set of slashes and asterisks (/**/). You’ll see and write both types of comments throughout the source code in the lessons.

An implicitly unwrapped optional is an optional that can also be used like a nonoptional value, without the need to unwrap the optional value each time it’s accessed. This is because an implicitly unwrapped optional is assumed to always have a value after that value is initially set, although the value can change. Implicitly unwrapped optional types are indicated with an exclamation mark (!) instead of a question mark (?).

  1. var implicitlyUnwrappedOptionalInt: Int!

You’ll rarely need to create implicitly unwrapped optionals in your own code. More often, you’ll see them used to keep track of outlets between an interface and source code (which you’ll learn about in a later lesson) and in the APIs you’ll see throughout the lessons.

Control Flow

Swift has two types of control flow statements. Conditional statements, like if and switch, check whether a condition is true—that is, if its value evaluates to the Boolean true—before executing a piece of code. Loops, like forin and while, execute the same piece of code multiple times.

An if statement checks whether a certain condition is true, and if it is, the if statement evaluates the code inside the statement. You can add an else clause to an if statement to define more complex behavior. Anelse clause can be used to chain if statements together, or it can stand on its own, in which case the elseclause is executed if none of the chained if statements evaluate to true.

  1. let number = 23
  2. if number < 10 {
  3. print("The number is small")
  4. } else if number > 100 {
  5. print("The number is pretty big")
  6. } else {
  7. print("The number is between 10 and 100")
  8. }

Statements can be nested to create complex, interesting behavior in a program. Here’s an example of an ifstatement with an else clause nested inside a forin statement (which iterates through each item in a collection in order, one-by-one).

  1. let individualScores = [75, 43, 103, 87, 12]
  2. var teamScore = 0
  3. for score in individualScores {
  4. if score > 50 {
  5. teamScore += 3
  6. } else {
  7. teamScore += 1
  8. }
  9. }
  10. print(teamScore)

Use optional binding in an if statement to check whether an optional contains a value.

  1. var optionalName: String? = "John Appleseed"
  2. var greeting = "Hello!"
  3. if let name = optionalName {
  4. greeting = "Hello, \(name)"
  5. }

If the optional value is nil, the conditional is false, and the code in braces is skipped. Otherwise, the optional value is unwrapped and assigned to the constant after let, which makes the unwrapped value available inside the block of code.

You can use a single if statement to bind multiple values. A where clause can be added to a case to further scope the conditional statement. In this case, the if statement executes only if the binding is successful for all of these values and all conditions are met.

  1. var optionalHello: String? = "Hello"
  2. if let hello = optionalHello where hello.hasPrefix("H"), let name = optionalName {
  3. greeting = "\(hello), \(name)"
  4. }

Switches in Swift are quite powerful. A switch statement supports any kind of data and a wide variety of comparison operations—it isn’t limited to integers and tests for equality. In this example, the switch statement switches on the value of the vegetable string, comparing the value to each of its cases and executing the one that matches.

  1. let vegetable = "red pepper"
  2. switch vegetable {
  3. case "celery":
  4. let vegetableComment = "Add some raisins and make ants on a log."
  5. case "cucumber", "watercress":
  6. let vegetableComment = "That would make a good tea sandwich."
  7. case let x where x.hasSuffix("pepper"):
  8. let vegetableComment = "Is it a spicy \(x)?"
  9. default:
  10. let vegetableComment = "Everything tastes good in soup."
  11. }

Notice how let can be used in a pattern to assign the value that matched that part of a pattern to a constant. Just like in an if statement, a where clause can be added to a case to further scope the conditional statement. However, unlike in an if statement, a switch case that has multiple conditions separated by commas executes when any of the conditions are met.

After executing the code inside the switch case that matched, the program exits from the switch statement. Execution doesn’t continue to the next case, so you don’t need to explicitly break out of the switch statement at the end of each case’s code.

Switch statements must be exhaustive. A default case is required, unless it’s clear from the context that every possible case is satisfied, such as when the switch statement is switching on an enumeration. This requirement ensures that one of the switch cases always executes.

You can keep an index in a loop by using a Range. Use the half-open range operator ( ..<) to make a range of indexes.

  1. var firstForLoop = 0
  2. for i in 0..<4 {
  3. firstForLoop += i
  4. }
  5. print(firstForLoop)

The half-open range operator (..<) doesn’t include the upper number, so this range goes from 0 to 3 for a total of four loop iterations. Use the closed range operator ( ...) to make a range that includes both values.

  1. var secondForLoop = 0
  2. for _ in 0...4 {
  3. secondForLoop += 1
  4. }
  5. print(secondForLoop)

This range goes from 0 to 4 for a total of five loop iterations. The underscore (_) represents a wildcard, which you can use when you don’t need to know which iteration of the loop is currently executing.

Functions and Methods

A function is a reusable, named piece of code that can be referred to from many places in a program.

Use func to declare a function. A function declaration can include zero or more parameters, written as name: Type, which are additional pieces of information that must be passed into the function when it’s called. Optionally, a function can have a return type, written after the ->, which indicates what the function returns as its result. A function’s implementation goes inside of a pair of curly braces ({}).

  1. func greet(name: String, day: String) -> String {
  2. return "Hello \(name), today is \(day)."
  3. }

Call a function by following its name with a list of arguments (the values you pass in to satisfy a function’s parameters) in parentheses. When you call a function, you pass in the first argument value without writing its name, and every subsequent value with its name.

  1. greet("Anna", day: "Tuesday")
  2. greet("Bob", day: "Friday")
  3. greet("Charlie", day: "a nice day")

Functions that are defined within a specific type are called methods. Methods are explicitly tied to the type they’re defined in, and can only be called on that type (or one of its subclasses, as you’ll learn about soon). In the earlier switch statement example, you saw a method that’s defined on the String type calledhasSuffix(), shown again here:

  1. let exampleString = "hello"
  2. if exampleString.hasSuffix("lo") {
  3. print("ends in lo")
  4. }

As you see, you call a method using the dot syntax. When you call a method, you pass in the first argument value without writing its name, and every subsequent value with its name. For example, this method on Arraytakes two parameters, and you only pass in the name for the second one:

  1. var array = ["apple", "banana", "dragonfruit"]
  2. array.insert("cherry", atIndex: 2)
  3. array

Classes and Initializers

In object-oriented programming, the behavior of a program is based largely on interactions between objects. An object is an instance of a class, which can be thought of as a blueprint for that object. Classes store additional information about themselves in the form of properties, and define their behavior using methods.

Use class followed by the class’s name to define a class. A property declaration in a class is written the same way as a constant or variable declaration, except that it’s in the context of a class. Likewise, method and function declarations are written the same way. This example declares a Shape class with a numberOfSidesproperty and a simpleDescription() method.

  1. class Shape {
  2. var numberOfSides = 0
  3. func simpleDescription() -> String {
  4. return "A shape with \(numberOfSides) sides."
  5. }
  6. }

Create an instance of a class—an object—by putting parentheses after the class name. Use dot syntax to access the properties and methods of the instance. Here, shape is an object that’s an instance of the Shapeclass.

  1. var shape = Shape()
  2. shape.numberOfSides = 7
  3. var shapeDescription = shape.simpleDescription()

This Shape class is missing something important: an initializer. An initializer is a method that prepares an instance of a class for use, which involves setting an initial value for each property and performing any other setup. Use init to create one. This example defines a new class, NamedShape, that has an initializer which takes in a name.

  1. class NamedShape {
  2. var numberOfSides = 0
  3. var name: String
  4. init(name: String) {
  5. self.name = name
  6. }
  7. func simpleDescription() -> String {
  8. return "A shape with \(numberOfSides) sides."
  9. }
  10. }

Notice how self is used to distinguish the name property from the name argument to the initializer. Every property needs a value assigned—either in its declaration (as with numberOfSides) or in the initializer (as withname).

You don’t call an initializer by writing init; you call it by putting parentheses with the appropriate arguments after the class name. When you call an initializer, you include all arguments names along with their values.

  1. let namedShape = NamedShape(name: "my named shape")

Classes inherit their behavior from their parent class. A class that inherits behavior from another class is called a subclass of that class, and the parent class is called a superclass. Subclasses include their superclass name after their class name, separated by a colon. A class can inherit from only one superclass, although that class can inherit from another superclass, and so on, resulting in a class hierarchy.

Methods on a subclass that override the superclass’s implementation are marked with override—overriding a method by accident, without override, is detected by the compiler as an error. The compiler also detects methods with override that don’t actually override any method in the superclass.

This example defines the Square class, a subclass of NamedShape.

  1. class Square: NamedShape {
  2. var sideLength: Double
  3. init(sideLength: Double, name: String) {
  4. self.sideLength = sideLength
  5. super.init(name: name)
  6. numberOfSides = 4
  7. }
  8. func area() -> Double {
  9. return sideLength * sideLength
  10. }
  11. override func simpleDescription() -> String {
  12. return "A square with sides of length \(sideLength)."
  13. }
  14. }
  15. let testSquare = Square(sideLength: 5.2, name: "my test square")
  16. testSquare.area()
  17. testSquare.simpleDescription()

Notice that the initializer for the Square class has three different steps:

  1. Setting the value of properties that the subclass, Square, declares.

  2. Calling the initializer of the superclass, NamedShape.

  3. Changing the value of properties defined by the superclass, NamedShape. Any additional setup work that uses methods, getters, or setters can also be done at this point.

Sometimes, initialization of an object needs to fail, such as when the values supplied as the arguments are outside of a certain range, or when data that’s expected to be there is missing. Initializers that may fail to successfully initialize an object are called failable initializers. A failable initializer can return nil after initialization. Use init? to declare a failable initializer.

  1. class Circle: NamedShape {
  2. var radius: Double
  3. init?(radius: Double, name: String) {
  4. self.radius = radius
  5. super.init(name: name)
  6. numberOfSides = 1
  7. if radius <= 0 {
  8. return nil
  9. }
  10. }
  11. override func simpleDescription() -> String {
  12. return "A circle with a radius of \(radius)."
  13. }
  14. }
  15. let successfulCircle = Circle(radius: 4.2, name: "successful circle")
  16. let failedCircle = Circle(radius: -7, name: "failed circle")

Initializers can have quite a few keywords associated with them. A designated initializer indicates that it’s one of the primary initializers for a class; any initializer within a class must ultimately call through to a designated initializer. A convenience initializer is a secondary initializer, which adds additional behavior or customization, but must eventually call through to a designated initializer. Designated and convenience initializers are indicated with the designated and convenience keywords, respectively.

A required keyword next to an initializer indicates that every subclass of the class that has that initializer must implement its own version of the initializer (if it implements any initializer).

Type casting is a way to check the type of an instance, and to treat that instance as if it’s a different superclass or subclass from somewhere else in its own class hierarchy.

A constant or variable of a certain class type may actually refer to an instance of a subclass behind the scenes. Where you believe this is the case, you can try to downcast to the subclass type using a type cast operator.

Because downcasting can fail, the type cast operator comes in two different forms. The optional form, as?, returns an optional value of the type you are trying to downcast to. The forced form, as!, attempts the downcast and force-unwraps the result as a single compound action.

Use the optional type cast operator (as?) when you’re not sure if the downcast will succeed. This form of the operator will always return an optional value, and the value will be nil if the downcast was not possible. This lets you check for a successful downcast.

Use the forced type cast operator (as!) only when you’re sure that the downcast will always succeed. This form of the operator will trigger a runtime error if you try to downcast to an incorrect class type.

This example shows the use of the optional type cast operator (as?) to check whether a shape in an array of shapes is a circle or a square. You increment the count of the squares and triangles variables by one each time the corresponding shape is found, printing the values at the end.

  1. class Triangle: NamedShape {
  2. init(sideLength: Double, name: String) {
  3. super.init(name: name)
  4. numberOfSides = 3
  5. }
  6. }
  7. let shapesArray = [Triangle(sideLength: 1.5, name: "triangle1"), Triangle(sideLength: 4.2, name: "triangle2"), Square(sideLength: 3.2, name: "square1"), Square(sideLength: 2.7, name: "square2")]
  8. var squares = 0
  9. var triangles = 0
  10. for shape in shapesArray {
  11. if let square = shape as? Square {
  12. squares++
  13. } else if let triangle = shape as? Triangle {
  14. triangles++
  15. }
  16. }
  17. print("\(squares) squares and \(triangles) triangles.")

Enumerations and Structures

Classes aren’t the only ways to define data types in Swift. Enumerations and structures have similar capabilities to classes, but can be useful in different contexts.

Enumerations define a common type for a group of related values and enable you to work with those values in a type-safe way within your code. Enumerations can have methods associated with them.

Use enum to create an enumeration.

  1. enum Rank: Int {
  2. case Ace = 1
  3. case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
  4. case Jack, Queen, King
  5. func simpleDescription() -> String {
  6. switch self {
  7. case .Ace:
  8. return "ace"
  9. case .Jack:
  10. return "jack"
  11. case .Queen:
  12. return "queen"
  13. case .King:
  14. return "king"
  15. default:
  16. return String(self.rawValue)
  17. }
  18. }
  19. }
  20. let ace = Rank.Ace
  21. let aceRawValue = ace.rawValue

In the example above, the raw-value type of the enumeration is Int, so you have to specify only the first raw value. The rest of the raw values are assigned in order. You can also use strings or floating-point numbers as the raw type of an enumeration. Use the rawValue property to access the raw value of an enumeration member.

Use the init?(rawValue:) initializer to make an instance of an enumeration from a raw value.

  1. if let convertedRank = Rank(rawValue: 3) {
  2. let threeDescription = convertedRank.simpleDescription()
  3. }

The member values of an enumeration are actual values, not just another way of writing their raw values. In fact, in cases where there isn’t a meaningful raw value, you don’t have to provide one.

  1. enum Suit {
  2. case Spades, Hearts, Diamonds, Clubs
  3. func simpleDescription() -> String {
  4. switch self {
  5. case .Spades:
  6. return "spades"
  7. case .Hearts:
  8. return "hearts"
  9. case .Diamonds:
  10. return "diamonds"
  11. case .Clubs:
  12. return "clubs"
  13. }
  14. }
  15. }
  16. let hearts = Suit.Hearts
  17. let heartsDescription = hearts.simpleDescription()

Notice the two ways that the Hearts member of the enumeration is referred to above: When a value is assigned to the hearts constant, the enumeration member Suit.Hearts is referred to by its full name because the constant doesn’t have an explicit type specified. Inside the switch, the enumeration member is referred to by the abbreviated form .Hearts because the value of self is already known to be a suit. You can use the abbreviated form anytime the value’s type is already known.

Structures support many of the same behaviors as classes, including methods and initializers. One of the most important differences between structures and classes is that structures are always copied when they are passed around in your code, but classes are passed by reference. Structures are great for defining lightweight data types that don’t need to have capabilities like inheritance and type casting.

Use struct to create a structure.

  1. struct Card {
  2. var rank: Rank
  3. var suit: Suit
  4. func simpleDescription() -> String {
  5. return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
  6. }
  7. }
  8. let threeOfSpades = Card(rank: .Three, suit: .Spades)
  9. let threeOfSpadesDescription = threeOfSpades.simpleDescription()


A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol doesn’t actually provide an implementation for any of these requirements—it only describes what an implementation will look like. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements. Any type that satisfies the requirements of a protocol is said to conform to that protocol.

Use protocol to declare a protocol.

  1. protocol ExampleProtocol {
  2. var simpleDescription: String { get }
  3. func adjust()
  4. }

Protocols can require that conforming types have specific instance properties, instance methods, type methods, operators, and subscripts. Protocols can require specific instance methods and type methods to be implemented by conforming types. These methods are written as part of the protocol’s definition in exactly the same way as for normal instance and type methods, but without curly braces or a method body.

Classes, structures, and enumerations adopt a protocol by listing its name after their name, separated by a colon. A type can adopt any number of protocols, which appear in a comma-separated list. If a class has a superclass, the superclass’s name must appear first in the list, followed by protocols. You conform to the protocol by implementing all of its requirements.

Here, SimpleClass adopts the ExampleProtocol protocol, and conforms to the protocol by implementing thesimpleDescription property and adjust() method.

  1. class SimpleClass: ExampleProtocol {
  2. var simpleDescription: String = "A very simple class."
  3. var anotherProperty: Int = 69105
  4. func adjust() {
  5. simpleDescription += " Now 100% adjusted."
  6. }
  7. }
  8. var a = SimpleClass()
  9. a.adjust()
  10. let aDescription = a.simpleDescription

Protocols are first-class types, which means they can be treated like other named types. For example, you can create an ExampleProtocol array and call adjust() on each of the instances in it (because any instance in that array would be guaranteed to implement adjust(), one of the protocol’s requirements).

  1. class SimpleClass2: ExampleProtocol {
  2. var simpleDescription: String = "Another very simple class."
  3. func adjust() {
  4. simpleDescription += " Adjusted."
  5. }
  6. }
  7. var protocolArray: [ExampleProtocol] = [SimpleClass(), SimpleClass(), SimpleClass2()]
  8. for instance in protocolArray {
  9. instance.adjust()
  10. }
  11. protocolArray

Swift and Cocoa Touch

Swift is designed to provide seamless interoperability with Cocoa Touch, the set of Apple frameworks you use to develop apps for iOS. As you walk through the rest of the lessons, it helps to have a basic understanding of how Swift interacts with Cocoa Touch.

So far, you’ve been working exclusively with data types from the Swift standard library. The Swift standard library is a set of data types and capabilities designed for Swift and baked into the language. Types likeString and Array are examples of data types you see in the standard library.

  1. let sampleString: String = "hello"
  2. let sampleArray: Array = [1, 2, 3.1415, 23, 42]

When writing iOS apps, you’ll be using more than the Swift standard library. One of the most frequently used frameworks in iOS app development is UIKit. UIKit contains useful classes for working with the UI (user interface) layer of your app.

To get access to UIKit, simply import it as a module into any Swift file or playground.

  1. import UIKit

After importing UIKit, you can use Swift syntax with UIKit types and with their methods, properties, and so on.

  1. let redSquare = UIView(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
  2. redSquare.backgroundColor = UIColor.redColor()

Many of the classes you’ll be introduced to in the lessons come from UIKit, so you’ll see this import statement often.

With this breadth of knowledge about Swift, you’re about to jump into making a full-fledged app in the next lesson. Although this lesson is the extent of playgrounds you’ll work with for now, remember that they can be a powerful tool in app development for anything from debugging, to visualizing complex code, to rapid prototyping.