Swift Quick Reference
Everything you need day‑to‑day – clean, fast, and safe.
Basic Syntax
// Entry point print("Hello, World!") // Semicolons are optional let x = 5 let y = 10; let z = 15 // Comments // Single line comment /* Multi‑line comment */
Variables & Constants
// Constants (let) – immutable let name = "Alice" let age: Int = 25 let pi = 3.14159 // Variables (var) – mutable var counter = 0 counter = 1 // Type inference let x = 42 // Int let y = 3.14 // Double let z = "hello" // String // Type annotation let score: Double = 95.5 let isActive: Bool = true // Lazy variables lazy var expensive = computeExpensive() // Computed properties var radius: Double = 5.0 var area: Double { get { return radius * radius * Double.pi } set { radius = sqrt(newValue / Double.pi) } }
Data Types
Basic Types
Int– 42Double– 3.14Float– 3.14Bool– true, falseString– "Hello"Character– 'A'
Compound Types
Array<T>– [1, 2, 3]Dictionary<K,V>– ["a": 1]Set<T>– Set([1, 2, 3])Tuple– (1, "Alice")Optional<T>– T?
Type Aliases
typealias UserID = Int typealias Completion = (Result) -> Void
Optionals
// Optional declaration var name: String? = nil var age: Int? = 25 // Unwrapping // 1. Force unwrap (!) – dangerous let unwrapped = name! // 2. Optional binding (if let) if let unwrapped = name { print(unwrapped) } // 3. Guard let guard let unwrapped = name else { return } print(unwrapped) // 4. Nil coalescing (??) let displayName = name ?? "Guest" // 5. Optional chaining (?.) let length = name?.count // 6. Compact map let numbers = ["1", "2", "a"].compactMap { Int($0) } // [1, 2] // Implicitly unwrapped optional (!) var assumedName: String! = "Alice"
Control Flow
if / else
if x > 0 { print("positive") } else if x == 0 { print("zero") } else { print("negative") }
switch
switch value { case 1: print("one") case 2: print("two") case 3...10: print("3-10") case let x where x % 2 == 0: print("even") default: print("other") }
Loops
// for‑in for i in 1...5 { print(i) } // Range operators 1...5 // closed range 1..<5 // half‑open ...5 // one‑sided // Iterate over collection for item in array { print(item) } for (index, value) in array.enumerated() { print("\(index): \(value)") } // while var i = 0 while i < 5 { print(i) i += 1 } // repeat‑while (do‑while) var i = 0 repeat { print(i) i += 1 } while i < 5
Functions
// Basic function func add(a: Int, b: Int) -> Int { return a + b } // Single‑expression function func add(a: Int, b: Int) -> Int { a + b } // Void function func log(message: String) { print(message) } // Multiple return values (tuple) func getCoordinates() -> (x: Int, y: Int) { return (10, 20) } let coord = getCoordinates() print(coord.x) // External parameter names func greet(name person: String) { print("Hello, \(person)") } greet(name: "Alice") // Omit external name (_) func greet(_ name: String) { print("Hello, \(name)") } greet("Alice") // Default parameters func greet(name: String, greeting: String = "Hello") { print("\(greeting), \(name)") } // Variadic parameters func sum(_ numbers: Int...) -> Int { numbers.reduce(0, +) } // Inout parameters func increment(_ x: inout Int) { x += 1 } var value = 5 increment(&value) // 6
Closures
// Closure expression let square = { (x: Int) -> Int in return x * x } print(square(5)) // 25 // Shorthand ($0, $1) let square = { $0 * $0 } // Trailing closure array.sorted { $0 < $1 } // Escaping closure var completionHandlers: [() -> Void] = [] func addCompletion(handler: @escaping () -> Void) { completionHandlers.append(handler) } // Autoclosure func assert(_ condition: @autoclosure () -> Bool) { if !condition() { print("Assertion failed") } } assert(2 + 2 == 4)
Classes & OOP
Basic Class
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
func greet() -> String {
return "Hello, \(name)"
}
}
// Usage
let person = Person(name: "Alice", age: 25)
print(person.greet())
Inheritance
class Student: Person {
var studentID: String
init(name: String, age: Int, studentID: String) {
self.studentID = studentID
super.init(name: name, age: age)
}
override func greet() -> String {
return "Hello, I'm student \(studentID)"
}
}
Structs (Value Types)
struct Point {
var x: Int
var y: Int
mutating func moveBy(dx: Int, dy: Int) {
x += dx
y += dy
}
}
// Member‑wise initialiser
let point = Point(x: 10, y: 20)
Enums
enum Status {
case active
case inactive
case pending
}
// Enum with associated values
enum Result {
case success(data: String)
case error(message: String)
case loading
}
// Enum with raw values
enum HTTPStatus: Int {
case ok = 200
case notFound = 404
case serverError = 500
}
Protocols
protocol Greetable {
var name: String { get }
func greet() -> String
}
// Protocol conformance
struct User: Greetable {
let name: String
func greet() -> String {
return "Hello, \(name)"
}
}
// Protocol extension (default implementation)
extension Greetable {
func greet() -> String {
return "Hello, \(name)"
}
}
Extensions
// Extend existing types extension String { var isEmail: Bool { return contains("@") && contains(".") } func reversed() -> String { return String(self.reversed()) } } print("alice@example.com".isEmail) // true
Collections
Array
// Create var array = [1, 2, 3, 4, 5] var empty: [Int] = [] var names = Array() // Access array[0] // first array.first // Optional array.last // Optional array.count array.isEmpty // Add / Remove array.append(6) array.insert(0, at: 0) array.remove(at: 2) array.removeLast() array.removeAll() // Iterate for item in array { print(item) } array.forEach { print($0) } // Transform array.map { $0 * 2 } array.filter { $0 % 2 == 0 } array.reduce(0, +) array.sorted() array.sorted { $0 > $1 }
Dictionary
// Create var dict = ["a": 1, "b": 2, "c": 3] var empty: [String: Int] = [:] // Access dict["a"] // Optional dict["d", default: 0] // with default dict.count dict.isEmpty // Add / Remove dict["d"] = 4 dict.removeValue(forKey: "b") // Iterate for (key, value) in dict { print("\(key): \(value)") } // Transform dict.mapValues { $0 * 2 } dict.filter { $0.value > 1 }
Set
// Create var set: Set = [1, 2, 3, 4, 5] var empty = Set() // Operations set.insert(6) set.remove(3) set.contains(2) // Set operations let a: Set = [1, 2, 3] let b: Set = [3, 4, 5] a.union(b) // {1, 2, 3, 4, 5} a.intersection(b) // {3} a.subtracting(b) // {1, 2} a.symmetricDifference(b) // {1, 2, 4, 5}
Error Handling
// Define error enum APIError: Error { case invalidURL case noData case decodingError } // Throwing function func fetchData() throws -> String { throw APIError.noData } // do‑catch do { let data = try fetchData() print(data) } catch APIError.noData { print("No data") } catch { print("Error: \(error)") } // try? (optional) let data = try? fetchData() // try! (force, dangerous) let data = try! fetchData() // Result type let result: Result= .success("Data") switch result { case .success(let data): print(data) case .failure(let error): print(error) }
Concurrency (async/await)
// Async function func fetchUser(id: Int) async -> User { // Simulate network request try await Task.sleep(nanoseconds: 1_000_000_000) return User(id: id, name: "Alice") } // Call async function Task { let user = await fetchUser(id: 123) print(user) } // Async sequence for await item in stream { print(item) } // Actor (thread‑safe) actor Counter { private var value = 0 func increment() { value += 1 } func getValue() -> Int { value } }
Memory Management
// Strong reference cycle with closures class SomeClass { var closure: (() -> Void)? init() { closure = { [weak self] in self?.doSomething() } } func doSomething() { } } // Capture lists [weak self] // weak reference [unowned self] // unowned reference // deinit deinit { print("Object deallocated") }
Common Standard Library Functions
String
str.countstr.uppercased()str.lowercased()str.trimmingCharacters(in: .whitespaces)str.split(separator: ",")str.contains("sub")str.hasPrefix("pre")str.hasSuffix("suf")str.replacingOccurrences(of: "old", with: "new")str.prefix(3)str.suffix(3)
Math
abs(x)ceil(x)floor(x)round(x)pow(x, y)sqrt(x)Int.random(in: 1...100)Double.random(in: 0..<1)max(a, b)min(a, b)
Best Practices
- Use
letovervar– prefer immutability. - Use optionals – rather than sentinel values.
- Use guard – for early exits and unwrapping.
- Use structs – for value types (prefer over classes).
- Use protocols – for abstraction and extension.
- Use extensions – to add functionality to types.
- Use enums – for finite sets of values.
- Use closures – for functional programming.
- Avoid force unwrap (
!) – use optional binding instead. - Use
weak– to break retain cycles in closures. - Use async/await – for asynchronous code.
- Use Result type – for error handling.
- Follow Swift naming conventions – camelCase, descriptive names.
- Use SwiftLint – to enforce code style.
📌 Quick Reference
Variables:
Optionals:
Collections: Array, Dictionary, Set
Closures:
Protocols: Define contracts, extensions for default impls
Struct vs Class: Struct (value type), Class (reference type)
Error handling:
Memory:
let (const), var (mutable)Optionals:
? (nullable), ?? (nil coalescing), if let, guard letCollections: Array, Dictionary, Set
Closures:
{ parameters in statements }Protocols: Define contracts, extensions for default impls
Struct vs Class: Struct (value type), Class (reference type)
Error handling:
try/catch, Result, throws, async/awaitMemory:
weak and unowned for retain cycles