Skip to main content
Swift, despite being a modern and safety-focused language, still has common anti-patterns that can lead to bugs, performance issues, and maintenance problems. Here are the most important anti-patterns to avoid when writing Swift code.
Force unwrapping optionals with ! can lead to runtime crashes. Use optional binding (if let), nil coalescing (??), or guard statements instead.
Implicitly unwrapped optionals (var name: Type!) should be avoided when possible. Use proper initialization or lazy properties instead.
Break up large view controllers into smaller, focused components using patterns like MVVM, Coordinator, or Clean Architecture.
Leverage Swift’s strong type system with enums, structs, and generics to make code safer and more expressive.
Singletons create hidden dependencies and make testing difficult. Use dependency injection instead.
Use Swift’s Result type for clearer and more consistent error handling in asynchronous code.
Use Swift’s access control modifiers (private, fileprivate, internal, public, open) to hide implementation details and create clear APIs.
Use [weak self] or [unowned self] in closures to avoid reference cycles and memory leaks.
Use Swift’s powerful collection methods like map, filter, reduce, compactMap, and flatMap for cleaner, more expressive code.
Avoid try! as it can cause crashes. Use proper error handling with do-catch blocks.
Use Swift’s property observers (willSet and didSet) to react to property changes automatically.
Use Swift’s throws and do-catch for error handling instead of returning nil or optional values.
Use structs and enums (value types) for data that should have value semantics, and classes for reference semantics.
Use lazy properties for expensive resources that might not be needed immediately or at all.
Use protocol extensions to share behavior across types without inheritance.
Use Swift’s modern concurrency features (async/await, actors, tasks) for cleaner asynchronous code.
Use property wrappers to encapsulate property storage and access patterns.
Use result builders (like SwiftUI’s ViewBuilder) for declarative, composable code.