No history yet

Swift Fundamentals

Your First Steps in Swift

Swift is a programming language created by Apple that's known for being powerful yet easy to read. It's designed to feel approachable, with clean syntax that avoids the clutter of older languages. Let's start with the classic first program.

print("Hello, world!")

That's it. This one line of code prints the message "Hello, world!" to the screen. Notice there's no semicolon at the end. Swift doesn't require them, which keeps the code looking clean.

Storing Information

To do anything useful, programs need to store information. In Swift, you use variables and constants to hold values. A variable is a value that can change, while a constant is a value that, once set, cannot be changed.

You declare constants with the let keyword and variables with var.

// A constant for a value that won't change
let pi = 3.14159

// A variable for a value that might change
var currentScore = 0
currentScore = 10 // This is okay

A good rule of thumb is to always use let unless you know you'll need to change the value later. This makes your code safer and easier to understand.

Every piece of data has a type. Swift is a type-safe language, which means it helps you be clear about the types of values your code can work with. Some basic types include:

  • String: For text, like "Hello".
  • Int: For whole numbers, like 42.
  • Double: For numbers with fractional components, like 3.14.
  • Bool: For true or false values, true or false.

Swift can usually figure out the type on its own, a feature called type inference. But you can also be explicit if you want.

let name = "Alice"         // Swift infers this is a String
let age = 30              // Swift infers this is an Int
let hasPet: Bool = true   // Explicitly typed as a Bool

Making Decisions and Repeating Tasks

Programs often need to make decisions or perform tasks repeatedly. This is handled by control flow statements.

To run code only when a certain condition is true, you use if, else if, and else.

let temperature = 75

if temperature > 80 {
    print("It's a hot day.")
} else if temperature < 60 {
    print("Better bring a jacket.")
} else {
    print("It feels great outside.")
}

To repeat a task, you can use a loop. The for-in loop is perfect for running a piece of code for each item in a collection, like an array.

let fruits = ["Apple", "Banana", "Cherry"]

for fruit in fruits {
    print("I love to eat \(fruit)s.")
}

Organizing Code

As programs grow, you'll want to organize your code into reusable blocks. Functions are a fundamental way to do this. A function is a named piece of code that you can "call" to perform a specific task.

Here’s how you define a function that takes a person's name as input and returns a greeting.

func greet(person: String) -> String {
    let greeting = "Hello, " + person + "!"
    return greeting
}

// Now we can call the function
print(greet(person: "Dave")) // Prints "Hello, Dave!"

Swift also has closures, which are self-contained blocks of functionality that can be passed around and used in your code. They're like functions without a name. You'll see them used frequently in Swift, especially for handling actions that happen later, like a button tap.

Creating Your Own Types

Beyond the basic types like String and Int, you can create your own custom types to model the concepts in your app. The two main ways to do this are with structures (struct) and classes (class). They are blueprints for creating objects.

Structures are great for simple data types. They are passed around by value, meaning a copy is made.

struct Book {
    var title: String
    var author: String
    var pageCount: Int
}

let myBook = Book(title: "The Hobbit", author: "J.R.R. Tolkien", pageCount: 310)

Classes are more powerful and support inheritance, which allows one class to build upon the features of another. They are passed by reference, meaning multiple variables can point to the exact same instance in memory.

class Vehicle {
    var currentSpeed = 0.0
    var description: String {
        return "traveling at \(currentSpeed) miles per hour"
    }
}

class Car: Vehicle { // Car inherits from Vehicle
    var hasSunroof = false
}

let myCar = Car()
myCar.currentSpeed = 55
myCar.hasSunroof = true
print("My car is \(myCar.description).")

Handling Problems Gracefully

Sometimes, things go wrong. A network request might fail or a file might not exist. Swift has a robust system for error handling that lets you respond to these situations cleanly.

A function that can fail is marked with the throws keyword. To call it, you use a do-catch block.

enum VendingMachineError: Error {
    case invalidSelection
    case outOfStock
}

func vend(item: String) throws {
    if item != "Chips" {
        throw VendingMachineError.invalidSelection
    }
    // ... more logic
}

do {
    try vend(item: "Candy")
} catch VendingMachineError.invalidSelection {
    print("That's not a valid item.")
} catch VendingMachineError.outOfStock {
    print("Sorry, that item is sold out.")
} catch {
    print("An unexpected error occurred.")
}

You wrap the code that might fail in a do block and use try to call the function. If an error occurs, the code jumps to the catch block, where you can handle the problem.

Quiz Questions 1/5

In Swift, what keyword is used to declare a value that cannot be changed once it has been assigned?

Quiz Questions 2/5

True or False: In Swift, a struct is a reference type, meaning when you assign it to a new variable, both variables point to the same instance in memory.

These are the fundamental building blocks of Swift. Mastering them is the first step toward building powerful and elegant applications for Apple's platforms.