Overview

The Swift language at a glance

Why Swift?

Swift is Apple’s modern, type-safe language for iOS, macOS, watchOS, tvOS, visionOS and server-side development. Designed for speed and safety, it offers expressive syntax, automatic memory management, and full interoperability with Objective-C. Swift 6.1 (released March 2025) is the current stable version.

Language Evolution

  1. Swift 5.x introduced module/ABI stability, async/await and actors.
  2. Swift 5.9 added macros, parameter packs and ownership borrowing.
  3. Swift 6 focuses on data-race safety, better diagnostics and faster compile times.

Programme Structure

How a Swift project is organised

Entry Points

  1. main.swift file in command-line tools executes top-level code sequentially.
  2. @main attribute can mark any type with a static main() method as the entry point (often used in SwiftUI apps).

Files & Modules

Each .swift file belongs to exactly one module (target) and may contain multiple declarations in any order. The compiler performs whole-module type checking by default.

Imports

// importing Apple frameworks
import Foundation
import SwiftUI

// importing a local module
import MyUtilities

Swift Package Manager (SPM)

  1. Package.swift manifest uses Package() DSL to declare products, targets and dependencies.
  2. Swift 6 adds package traits for platform-specific compilation flags.

Note: Xcode wraps SPM seamlessly—every Xcode project is also a Swift package under the hood.

Basic Syntax

Declarations, literals and operators

Variables & Constants

let maximumLoginAttempts = 3       // constant
var currentAttempt = 0             // mutable variable

Type Annotations & Inference

var message: String = "Hello"
var pi = 3.14159                   // Double inferred

Operators

  1. Standard arithmetic + − * / %
  2. Range ..HalfOpen, ...Closed
  3. Custom operators via operator declaration.

Control Flow

Conditionals, pattern matching and loops

Conditionals

if age >= 18 {
    print("Adult")
} else if age > 12 {
    print("Teen")
} else {
    print("Child")
}

Pattern Matching with switch

switch coordinates {
case (0, 0):
    print("Origin")
case (let x, 0):
    print("On x-axis at \(x)")
case (-2...2, -2...2):
    print("Near")
default:
    print("Far")
}

Loops & Sequences

  1. for-in over arrays, dictionaries, ranges.
  2. while & repeat-while.

Functions & Closures

Parameter syntax, generics and higher-order code

Function Basics

func greet(_ name: String, from city: String = "") -> String {
    "Hello \(name)!" + (city.isEmpty ? "" : " From \(city).")
}

Inout, Variadics & Parameter Packs (Swift 5.9+)

func swapTwoValues<T>(_ a: inout T, _ b: inout T) { … }

func mean<T: BinaryInteger>(_ numbers: repeat T) -> Double { … }

Closures

let sorted = names.sorted { $a, $b in a < b }

Types & OOP Constructs

Structures, classes, enums and access control

Structures & Value Semantics

struct Point {
    var x: Double
    var y: Double
    mutating func translate(dx: Double, dy: Double) {
        x += dx; y += dy
    }
}

Classes & Reference Semantics

class Vehicle {
    var currentSpeed = 0.0
    func description() -> String { "speed \(currentSpeed)" }
}

Enumerations with Associated Values

enum Barcode {
    case upc(Int, Int, Int, Int)
    case qr(String)
}

Access Control

  1. open > public > package (Swift 6) > internal > fileprivate > private

Protocols & Extensions

Interfaces, default implementations and protocol-oriented design

Defining Protocols

protocol Drawable {
    func draw(in ctx: CGContext)
}

Protocol Extensions

extension Drawable {
    func renderPNG() -> Data { … }
}

Note: Protocol-oriented programming encourages composing behaviour via protocols + extensions rather than deep class hierarchies.

Generics

Type-safe abstraction without sacrifice

Generic Functions & Types

struct Stack<Element> {
    private var items: [Element] = []
    mutating func push(_ item: Element) { items.append(item) }
    mutating func pop() -> Element { items.removeLast() }
}

Associated Types & Where Clauses

protocol Container {
    associatedtype Item
    var count: Int { get }
    subscript(index: Int) -> Item { get }
}

extension Stack: Container { … }

Concurrency (Async/Await & Actors)

Structured concurrency and data-race safety

Async Functions

func fetchImage() async throws -> UIImage {
    let (url, _) = try await URLSession.shared.data(from: imageURL)
    return UIImage(data: url)!
}

Actors & Isolation

actor Counter {
    private var value = 0
    func increment() { value += 1 }
    func read() -> Int { value }
}

Swift 6 tightens isolation rules and introduces compile-time data-race safety.

Memory Management & Ownership

ARC, borrowing and copy-on-write

Automatic Reference Counting (ARC)

ARC inserts retain/release calls at compile time for class instances. Structs and enums are value types using copy-on-write optimisation.

Ownership Keywords (Swift 5.9+)

func process(buffer consume inout Data) { … }

Borrowing lets the compiler prove exclusivity, enabling aggressive optimisation and future stack allocation.

Attributes, Macros & Result Builders

Meta-programming in modern Swift

Common Attributes

  1. @available for version checks
  2. @discardableResult to silence warnings
  3. @MainActor for UI-bound APIs

Macros (Swift 5.9)

#stringify(x + y)       // expands to "(x + y)"
#warning("Deprecated")  // compiler diagnostic

Result Builders

@resultBuilder
struct HTMLBuilder { … }

func page(@HTMLBuilder body: () -> String) -> String { body() }

Tooling & Compilation

Xcode, swiftc and build flags

swiftc CLI

swiftc -warn-concurrency -strict-concurrency=complete main.swift -o app

Linting & Formatters

  1. swift-format (official)
  2. SwiftLint (community)

Best Practices

Idiomatic patterns for production code

  1. Prefer value types; choose class only when reference semantics are essential.
  2. Mark everything internal by default; expose minimal public API.
  3. Handle errors via throw/try instead of optionals when failure is exceptional.
  4. Adopt async/await for all new I/O APIs.
  5. Write exhaustive switch statements on enums to profit from compiler checks.