Swift Cheat Sheet
Swift reference with optionals, closures, protocols, async/await, and concurrency. Copy-ready code for iOS and macOS developers.
Variables
| Syntax | Description | Example |
|---|---|---|
| Mutable variable declaration | var count = 0 | |
| Immutable constant (preferred) | let pi = 3.14159 | |
| Explicit type annotation | var name: String = "Alice" | |
| Basic types | let age: Int = 30 | |
| Output to console | print("Hello \(name)") | |
| String interpolation | "Score: \(score) points" | |
| Create a type alias | typealias UserID = Int |
Optionals
| Syntax | Description | Example |
|---|---|---|
| Optional type (may be nil) | var email: String? | |
| Optional binding (if let) | if let name = user.name { print(name) } | |
| Guard statement (early return) | guard let id = params["id"] else { return } | |
| Nil coalescing operator | let name = input ?? "Anonymous" | |
| Force unwrap (crashes if nil) | let name = optionalName! // dangerous | |
| Optional chaining | user?.address?.city | |
| Optional / forced type cast | let text = value as? String |
Collections
| Syntax | Description | Example |
|---|---|---|
| Array literal | var fruits = ["apple", "banana"] | |
| Add element to array | fruits.append("cherry") | |
| Insert at index | arr.insert("first", at: 0) | |
| Remove element at index | arr.remove(at: 0) | |
| Check if array contains element | fruits.contains("apple") // true | |
| Count elements / check empty | if arr.isEmpty { ... } | |
| Sort or reverse array | [3,1,2].sorted() // [1,2,3] | |
| Transform each element | [1,2,3].map { $0 * 2 } // [2,4,6] | |
| Filter elements | [1,2,3].filter { $0 > 1 } // [2,3] | |
| Reduce to single value | [1,2,3].reduce(0, +) // 6 | |
| Map and remove nils | ["1","a"].compactMap { Int($0) } // [1] | |
| Map and flatten results | [[1,2],[3]].flatMap { $0 } // [1,2,3] | |
| Dictionary | var user: [String: Any] = ["name": "Alice"] | |
| Set (unique values) | var tags: Set<String> = ["swift", "ios"] | |
| Iterate with index | for (i, val) in arr.enumerated() { ... } | |
| Combine two sequences | for (a, b) in zip(names, ages) { ... } |
Control Flow
| Syntax | Description | Example |
|---|---|---|
| Conditional branching | if score > 90 { ... } else { ... } | |
| Switch (exhaustive, no fallthrough) | switch dir { case .north: ... default: ... } | |
| For-in loop | for fruit in fruits { print(fruit) } | |
| Range loop (exclusive) | for i in 0..<10 { print(i) } | |
| Range loop (inclusive) | for i in 1...5 { print(i) } | |
| While loop | while count < 10 { count += 1 } | |
| Repeat-while (do-while) | repeat { try() } while !success | |
| Add conditions to patterns | for i in arr where i > 0 { ... } | |
| Error handling | do { try load() } catch { print(error) } | |
| Optional try / forced try | let data = try? fetchData() | |
| Execute when leaving scope | defer { file.close() } |
Functions
| Syntax | Description | Example |
|---|---|---|
| Function declaration | func greet(name: String) -> String { ... } | |
| Omit argument label | func double(_ x: Int) -> Int { x * 2 } | |
| External/internal parameter names | func move(to point: CGPoint) { ... } | |
| Default parameter value | func connect(port: Int = 8080) { ... } | |
| Variadic parameters | func sum(_ nums: Int...) -> Int { nums.reduce(0, +) } | |
| In-out parameter (pass by reference) | func swap(_ a: inout Int, _ b: inout Int) { ... } | |
| Closure expression | let double = { (x: Int) -> Int in x * 2 } | |
| Closure outlives function scope | func fetch(completion: @escaping (Data) -> Void) | |
| Last closure param outside parens | arr.sorted { $0 < $1 } |
OOP
| Syntax | Description | Example |
|---|---|---|
| Define a struct (value type) | struct Point { var x: Double; var y: Double } | |
| Define a class (reference type) | class Vehicle { var speed = 0 } | |
| Initializer (constructor) | init(name: String) { self.name = name } | |
| Inheritance | class Car: Vehicle { var doors = 4 } | |
| Define a protocol (interface) | protocol Drawable { func draw() } | |
| Add methods to existing type | extension String { var isBlank: Bool { ... } } | |
| Enumeration | enum Direction { case north, south, east, west } | |
| Enum with raw values | enum Status: Int { case active = 1, inactive = 0 } | |
| Enum cases with data | enum Result { case success(Data); case failure(Error) } | |
| Type-level properties/methods | static let shared = MyService() |
Concurrency
| Syntax | Description | Example |
|---|---|---|
| Asynchronous function | func fetchUser() async throws -> User { ... } | |
| Create async task | Task { let user = try await fetchUser() } | |
| Concurrent binding | async let a = fetch1(); async let b = fetch2() | |
| Actor (thread-safe type) | actor Counter { var count = 0 } | |
| Structured concurrency group | await withTaskGroup(of: Data.self) { group in ... } |
Frequently asked questions
What's the difference between struct and class in Swift?
Structs are value types (copied on assignment), classes are reference types (shared reference). Structs get automatic memberwise initializers and are generally faster. Use structs by default; use classes when you need inheritance or shared mutable state.
What are optionals and why does Swift have them?
Optionals represent a value that may or may not exist (Type?). Unlike other languages where any variable can be null, Swift makes absence explicit. This eliminates null pointer crashes - you must handle the nil case to access the value.
What's the difference between guard and if let?
Both unwrap optionals, but guard exits scope on failure (return, throw, break) and makes the unwrapped value available afterward. if let creates a new scope. Use guard for preconditions, if let for optional branching.
How does Swift concurrency (async/await) work?
Swift's structured concurrency uses async functions that can suspend with await. Tasks run concurrently, actors protect shared state, and async let enables parallel execution. It replaces callback-based patterns with linear, readable code.
Should I use SwiftUI or UIKit?
SwiftUI is the future for new projects - it's declarative, cross-platform (iOS, macOS, watchOS), and requires less code. UIKit is mature with more features and community resources. Many apps use both. For new projects, start with SwiftUI.
What is protocol-oriented programming?
Instead of class hierarchies, Swift uses protocols to define capabilities and extensions to provide default implementations. Types can conform to multiple protocols, enabling composition over inheritance. It's more flexible and testable.
Go from reference to real skills
Cheat sheets are great for quick lookups. Our in-depth courses take you from the fundamentals to professional-level mastery.
Browse all courses