Introduction to Swift
What Is Swift?
Section titled “What Is Swift?”Swift is a general-purpose, compiled programming language developed by Apple for building applications across all Apple platforms — iOS, iPadOS, macOS, watchOS, tvOS, and visionOS. It was designed to be safe, fast, and expressive, replacing Objective-C as the primary language for Apple ecosystem development.
Swift is open source (Apache 2.0 licence) and has an active community contributing to its development on platforms beyond Apple, including Linux and Windows.
History and Evolution
Section titled “History and Evolution”Swift 1.0 (2014)
Section titled “Swift 1.0 (2014)”- Announced at WWDC 2014 by Chris Lattner
- Introduced as a modern replacement for Objective-C
- Key design goals: safety (memory management via ARC), speed (LLVM-based compiler), and expressiveness (clean syntax)
- Interoperable with Objective-C — existing Cocoa frameworks were accessible
Swift 2.0 (2015)
Section titled “Swift 2.0 (2015)”guardstatement for early exitserror handlingwiththrow,try,catch- Protocol extensions with default implementations
deferstatement for cleanup- Availability checking with
@available
Swift 3.0 (2016)
Section titled “Swift 3.0 (2016)”- Major syntax changes to improve consistency and readability
- Renamed parameter labels became first-class citizens
#keyPathfor type-safe key paths- Swift on Linux (open source release)
- API Design Guidelines established
Swift 4.0 (2017)
Section titled “Swift 4.0 (2017)”Codableprotocol for JSON and plist serialisationStringbecame aCollectionofCharacter- Multi-line string literals
- Improved
keypathswith\.syntax
Swift 5.0 (2019)
Section titled “Swift 5.0 (2019)”- ABI stability — Swift standard library is embedded in the OS, binary compatibility across Swift versions
Resulttype in the standard library@dynamicCallableand@dynamicMemberLookup- Raw strings with
#"..."# isMultiple(of:)and other standard library additions
Swift 5.1 through 5.10
Section titled “Swift 5.1 through 5.10”- Property wrappers (
@Published,@State,@Binding,@ObservedObject,@EnvironmentObject) - Opaque return types (
some View) @mainattribute for app entry pointanykeyword for existential types (Swift 5.6+)if letshorthand andswitchonifexpressions- Typed throws (Swift 5.9+)
- Macro system (Swift 5.9+)
Swift 6.0 (2024)
Section titled “Swift 6.0 (2024)”- Strict concurrency checking enabled by default
- Complete
Sendableenforcement - Region-based isolation for more granular concurrency control
- Improved type system for safer async code
- Bitwise copyable protocol
Swift vs Other Languages
Section titled “Swift vs Other Languages”| Feature | Swift | Python | TypeScript | Rust |
|---|---|---|---|---|
| Type system | Strong, safe | Dynamic | Gradual | Strong |
| Memory management | ARC | GC | GC | Ownership |
| Compilation | Compiled | Interpreted | Compiled (JS) | Compiled |
| Concurrency | async/await | async/await | async/await | async/await |
| Primary domain | Apple | General | Web | Systems |
| Null safety | Optionals | None | Union/null | Option |
Setting Up the Development Environment
Section titled “Setting Up the Development Environment”Installing Xcode
Section titled “Installing Xcode”Xcode is the primary IDE for Swift development on Apple platforms. It includes the Swift compiler, Interface Builder, Instruments for profiling, and the iOS/macOS simulators.
- Download Xcode from the Mac App Store or developer.apple.com
- Open Xcode and accept the licence agreement
- Install the command-line tools:
xcode-select --install - Verify installation:
swift --version
$ swift --versionApple Swift version 5.10Target: arm64-apple-macosx14.0Swift Playgrounds
Section titled “Swift Playgrounds”Swift Playgrounds provide an interactive environment for experimenting with Swift code without creating a full project.
In Xcode:
- File > New > Playground
- Choose “Blank” for a general playground
- Write code and see results instantly in the sidebar
Swift Playgrounds app (iPad):
- Download from the App Store
- Interactive tutorials and coding challenges built in
- Supports SwiftUI for real-time UI preview
// Swift Playground exampleimport SwiftUI
struct ContentView: View { var body: some View { VStack { Text("Hello, Swift!") .font(.largeTitle) Circle() .fill(Color.blue) .frame(width: 100, height: 100) } }}
#Preview { ContentView()}Creating a New Xcode Project
Section titled “Creating a New Xcode Project”- Open Xcode > File > New > Project
- Select the platform (iOS, macOS, etc.)
- Choose the template:
- App — Standard SwiftUI or UIKit application
- Framework — Reusable library
- Command Line Tool — Terminal-based Swift program
- Configure project options:
- Product Name
- Team (for signing)
- Organisation Identifier
- Interface: SwiftUI or Storyboard
- Language: Swift
- Choose a location and click Create
Swift Command Line Tools
Section titled “Swift Command Line Tools”For development on Linux or for server-side Swift, install the Swift toolchain directly:
## Install Swift on Ubuntusudo apt install swift
## Verifyswift --version
# Run a Swift file directlyswift main.swift
# Enter the REPLswiftSwift Package Manager (SPM)
Section titled “Swift Package Manager (SPM)”SPM is Apple”s built-in dependency management and build tool. It integrates with Xcode and works from the command line.
Package Structure
Section titled “Package Structure”MyPackage/ Package.swift // Package manifest Sources/ MyPackage/ MyFile.swift Tests/ MyPackageTests/ MyFileTests.swiftPackage.swift Manifest
Section titled “Package.swift Manifest”import PackageDescription
let package = Package( name: "MyPackage", platforms: [ .iOS(.v17), .macOS(.v14) ], products: [ .library( name: "MyPackage", targets: ["MyPackage"] ), .executable( name: "MyCLI", targets: ["MyCLI"] ) ], dependencies: [ .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.3.0"), .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.8.0"), ], targets: [ .target( name: "MyPackage", dependencies: ["Alamofire"] ), .executableTarget( name: "MyCLI", dependencies: [ "MyPackage", .product(name: "ArgumentParser", package: "swift-argument-parser") ] ), .testTarget( name: "MyPackageTests", dependencies: ["MyPackage"] ) ])Common SPM Commands
Section titled “Common SPM Commands”# Create a new packageswift package init --type libraryswift package init --type executable
# Build the packageswift build
# Run testsswift test
# Generate Xcode projectswift package generate-xcodeproj
# Update dependenciesswift package update
# Resolve dependenciesswift package resolve
# Clean build artifactsswift package cleanAdding Dependencies in Xcode
Section titled “Adding Dependencies in Xcode”- File > Add Package Dependencies
- Enter the package repository URL
- Select the version rule (Up to Next Major, Up to Next Minor, or Exact)
- Choose the products to add to the target
Creating a Local Swift Package
Section titled “Creating a Local Swift Package”For modular code within a workspace:
- File > New > Package
- Name the package and choose its location
- Add it as a dependency to your main app target
Hello World
Section titled “Hello World”Command Line
Section titled “Command Line”print("Hello, World!")
// Variables and constantslet language = "Swift"var version = 6.0
print("\(language) version \(version)")// Swift version 6.0
// String interpolation with expressionslet count = 42print("There are \(count) items. That's \(count % 2 == 0 ? "even" : "odd").")// There are 42 items. That's even.SwiftUI App (Swift 5.3+)
Section titled “SwiftUI App (Swift 5.3+)”import SwiftUI
@mainstruct MyApp: App { var body: some Scene { WindowGroup { ContentView() } }}
struct ContentView: View { @State private var name = ""
var body: some View { VStack(spacing: 20) { Text("Hello, \(name.isEmpty ? "World" : name)!") .font(.title) TextField("Enter your name", text: $name) .textFieldStyle(.roundedBorder) .padding() } .padding() }}Swift’s Design Philosophy
Section titled “Swift’s Design Philosophy”Safety
Section titled “Safety”Swift eliminates entire categories of bugs at compile time:
- No null pointer dereference — optionals force you to handle the absence of values
- No buffer overflow — array bounds are always checked
- No uninitialized variables — all variables must be initialised before use
- No integer overflow by default — arithmetic operations trap on overflow
- Memory safety — ARC manages memory automatically; strong reference cycles are caught at compile time with
@escapingand lifetime annotations
Performance
Section titled “Performance”Swift matches or exceeds C++ performance in many benchmarks:
- LLVM backend generates highly optimised native code
- Value semantics for structs enable optimisations impossible with reference types
- Copy-on-write for collections avoids unnecessary data copying
- Generic specialisation eliminates the overhead of abstraction
- Whole-module optimisation enables cross-function inlining
Expressiveness
Section titled “Expressiveness”Swift combines the performance of a systems language with the ergonomics of a scripting language:
- Protocol-oriented programming enables flexible abstractions without inheritance
- Property wrappers encapsulate storage logic cleanly
- Result builders create declarative DSLs (used by SwiftUI)
- Pattern matching handles complex data decomposition elegantly
Key Concepts Overview
Section titled “Key Concepts Overview”Type Safety and Inference
Section titled “Type Safety and Inference”Swift is type-safe: every value has a known type at compile time. The compiler infers types when possible, but you can always be explicit.
let inferredInt = 42 // Int (inferred)let explicitDouble: Double = 42 // Double (explicit)let pi = 3.14159 // Double (inferred)
// Type mismatch is a compile errorlet message: String = 42 // error: cannot convert value of type 'Int' to specified type 'String'Optionals
Section titled “Optionals”Optionals represent the absence of a value, eliminating null pointer errors.
var name: String? = "Alice"name = nil // Valid: optionals can be nil
let length = name?.count // Int?, not IntValue Types vs Reference Types
Section titled “Value Types vs Reference Types”Structs are value types (copied on assignment); classes are reference types (shared).
struct Point { var x: Int var y: Int}
var a = Point(x: 1, y: 2)var b = a // Copy -- independentb.x = 10print(a.x) // 1 (unchanged)Protocol-Oriented Programming
Section titled “Protocol-Oriented Programming”Swift favours protocols over inheritance for defining shared behaviour.
protocol Identifiable { var id: String { get } var displayName: String { get }}
struct User: Identifiable { let id: String let displayName: String}
func greet(_ subject: Identifiable) { print("Hello, \(subject.displayName)")}Swift Ecosystem
Section titled “Swift Ecosystem”Major Frameworks
Section titled “Major Frameworks”- SwiftUI — Declarative UI framework for all Apple platforms
- UIKit / AppKit — Imperative UI frameworks (pre-SwiftUI, still widely used)
- Foundation — Core utilities (dates, data, networking, JSON)
- Combine — Reactive programming framework (publishers and subscribers)
- Core Data — Object graph and persistence framework
- ARKit — Augmented reality framework
- Metal — Low-level GPU programming
Popular Third-Party Libraries
Section titled “Popular Third-Party Libraries”| Library | Purpose |
|---|---|
| Alamofire | HTTP networking |
| Kingfisher | Image downloading and caching |
| SnapKit | Auto Layout DSL |
| SwiftLint | Code style and conventions |
| SwiftFormat | Code formatting |
| RxSwift | Reactive extensions |
| The Composable Architecture | State management architecture |
| Alamofire | HTTP networking |
Server-Side Swift
Section titled “Server-Side Swift”Swift is a capable server-side language with frameworks like:
- Vapor — The most popular web framework for Swift
- Hummingbird — Lightweight, high-performance HTTP server
- SwiftNIO — Apple’s async event-driven networking framework (foundation for Vapor)
Swift Version Compatibility
Section titled “Swift Version Compatibility”Use #if compiler(>=5.9) and @available to handle version differences:
// Availability checking for OS versions@available(iOS 17, macOS 14, *)func useNewAPI() { // Code requiring iOS 17+ / macOS 14+}
// Compiler version checking#if compiler(>=5.9)// Swift 5.9+ specific codefunc typedThrow() throws(some Error) { // ...}#else// Fallback for older versions#endifSummary
Section titled “Summary”Swift is a modern, safe, and fast programming language designed for the Apple ecosystem but extending well beyond it. Its combination of protocol-oriented design, value semantics, strong type safety, and modern concurrency support makes it well-suited for applications ranging from mobile UI to server-side services.
Intuition
Section titled “Intuition”Swift is Apple’s answer to the question: can we have C++ performance with Python-like safety? The language uses Automatic Reference Counting for memory management, catching reference cycles at compile time. Value types (structs) versus reference types (classes) is a core design decision that affects performance and thread safety. Protocol-oriented programming favours composition over inheritance, letting you build flexible abstractions without the fragile base class problem.
Cross-References
Section titled “Cross-References”- [[swift/01-basics/1_variables-and-types]] - Type inference and optionals
- [[swift/03-oop/1_classes-and-structs]] - Value versus reference type semantics
- [[swift/04-advanced/1_error-handling]] - Error handling with do-catch
- [[swift/04-advanced/2_concurrency]] - Structured concurrency with async/await
Common Mistakes
Section titled “Common Mistakes”- Confusing value types and reference types: Structs are value types (copied on assignment) and classes are reference types (shared reference). Beginners often use classes when structs suffice, leading to unexpected shared state. Prefer structs unless you need inheritance or reference semantics.
- Force-unwrapping optionals carelessly: Using
!on an optional crashes at runtime if the value isnil. Always useif let,guard let, or the nil-coalescing operator??to safely unwrap optionals. - Ignoring ARC and creating retain cycles: Strong reference cycles between classes (e.g., parent-child relationships) cause memory leaks. Use
weakorunownedreferences to break cycles, especially in closures and delegate patterns. - Using
varwhereletshould be used: Swift encourages immutability. Declaring variables withvarwhen they are never mutated makes code harder to reason about and prevents compiler optimisations. Default toletand switch tovaronly when reassignment is needed.