--- name: swift description: "Language-specific super-code guidelines for swift." risk: safe source: community date_added: "2026-06-16" --- # Swift: Idiomatic Efficiency Reference ## Table of Contents 1. [Optionals](#optionals) 2. [Collections & Functional Transforms](#collections) 3. [Value vs Reference Types](#value-types) 4. [Error Handling](#errors) 5. [Concurrency](#concurrency) 6. [Protocol-Oriented Design](#protocols) 7. [Anti-patterns specific to Swift](#antipatterns) --- ## 1. Optionals {#optionals} ```swift // ❌ Force unwrap let name = user.name! // ✅ — guard or if-let guard let name = user.name else { return } ``` ```swift // ❌ Nested if-let pyramid if let user = fetchUser() { if let address = user.address { if let city = address.city { display(city) } } } // ✅ — chained optional binding if let city = fetchUser()?.address?.city { display(city) } // or guard-let for early exit guard let city = fetchUser()?.address?.city else { return } display(city) ``` ```swift // ❌ Ternary for default let name = user.name != nil ? user.name! : "Unknown" // ✅ let name = user.name ?? "Unknown" ``` ```swift // ❌ Optional map when if-let is clearer for side effects user.name.map { display($0) } // ✅ — map for transforms, if-let for side effects let upper = user.name.map { $0.uppercased() } if let name = user.name { display(name) } ``` --- ## 2. Collections & Functional Transforms {#collections} ```swift // ❌ Imperative filter + map var result: [String] = [] for item in items { if item.isActive { result.append(item.name.uppercased()) } } // ✅ let result = items .filter(\.isActive) .map { $0.name.uppercased() } ``` ```swift // ❌ Manual dictionary construction var dict: [String: User] = [:] for user in users { dict[user.id] = user } // ✅ let dict = Dictionary(uniqueKeysWithValues: users.map { ($0.id, $0) }) // or with possible duplicates: let dict = Dictionary(grouping: users, by: \.department) ``` ```swift // ❌ Checking isEmpty then accessing first if !items.isEmpty { process(items[0]) } // ✅ if let first = items.first { process(first) } ``` ```swift // ❌ Index-based loop for i in 0.. Data? { ... } // caller doesn't know why it failed // ✅ func parse(_ input: String) throws -> Data { ... } ``` ```swift // ❌ try! in production code let data = try! JSONDecoder().decode(User.self, from: jsonData) // ✅ do { let data = try JSONDecoder().decode(User.self, from: jsonData) } catch { logger.error("decode failed: \(error)") throw AppError.decodingFailed(underlying: error) } ``` ```swift // ❌ Generic Error type enum AppError: Error { case generic(String) } // ✅ — specific, actionable error cases enum AppError: Error { case networkUnreachable case invalidInput(field: String, reason: String) case unauthorized } ``` ```swift // ❌ Catching all errors and ignoring do { try riskyOperation() } catch { } // ✅ do { try riskyOperation() } catch let error as NetworkError { handleNetworkError(error) } catch { throw error // rethrow unknown } ``` --- ## 5. Concurrency {#concurrency} ```swift // ❌ Callback-based async (pyramid of doom) fetchUser { user in fetchPosts(for: user) { posts in fetchComments(for: posts.first!) { comments in display(comments) } } } // ✅ (Swift 5.5+) let user = try await fetchUser() let posts = try await fetchPosts(for: user) let comments = try await fetchComments(for: posts[0]) display(comments) ``` ```swift // ❌ Sequential awaits for independent work let a = try await fetchA() let b = try await fetchB() // ✅ async let a = fetchA() async let b = fetchB() let (resultA, resultB) = try await (a, b) ``` ```swift // ❌ DispatchQueue.main.async for UI updates in async context DispatchQueue.main.async { label.text = result } // ✅ await MainActor.run { label.text = result } // or mark the function/class @MainActor ``` **Use `actor` for mutable shared state instead of manual locks/queues.** --- ## 6. Protocol-Oriented Design {#protocols} ```swift // ❌ Deep class inheritance hierarchy class Animal { ... } class Dog: Animal { ... } class GuideDog: Dog { ... } // ✅ — protocols + composition protocol Animal { var name: String { get } } protocol Trainable { func train() } struct Dog: Animal, Trainable { ... } ``` ```swift // ❌ Protocol with default implementations for everything protocol Renderable { func render() } extension Renderable { func render() { /* default */ } } // Every conformer uses default — protocol serves no purpose // ✅ — only default implementations that provide genuine shared logic ``` ```swift // ❌ Associated type when generic parameter suffices protocol Container { associatedtype Element func get() -> Element } // ✅ — use `some` or generic parameter for simple cases func process(_ item: some Equatable) { ... } ``` --- ## 7. Anti-patterns specific to Swift {#antipatterns} | Anti-pattern | Preferred | |---|---| | Force unwrap `!` in production code | `guard let` / `if let` / `??` | | `try!` outside tests | `do/catch` | | `class` for plain data | `struct` | | Deep inheritance hierarchies | protocol composition | | `@objc` when pure Swift works | native Swift types | | `NSArray` / `NSDictionary` | `Array` / `Dictionary` | | `DispatchQueue` in async/await code | `actor` / `MainActor` | | Implicitly unwrapped optionals as fields | regular optionals or non-optional with init | | `Any` / `AnyObject` everywhere | generics with protocol constraints | | Massive `switch` over string values | enum with raw values | | Singleton pattern (global mutable state) | dependency injection | ## Limitations - These are language-specific guidelines and do not cover overall architectural decisions. - Over-compression might reduce readability; apply judgement.