Design Patterns in Swift with Code Examples for iOS

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Design Patterns in Swift: A Practical Guide for iOS/macOS Developers



Design patterns are proven solutions to typical problems in software development. For iOS/macOS developers, knowledge of Swift patterns is an essential skill that enables creating scalable, testable, and maintainable applications. In this article, we'll cover 4 key patterns with real code examples.



1. Singleton

One of the most popular patterns in iOS development. It ensures that a class has only one instance and provides a global access point to it. Used for managing shared resources: UserDefaults, NetworkManager, Database.



Singleton Implementation in Swift

class NetworkManager {    static let shared = NetworkManager()        private init() { }        func fetchData(from url: URL) {        // request logic        print("Data received from \\(url)")    }}

// UsageNetworkManager.shared.fetchData(from: URL(string: "https://api.example.com")!)


Important: In Swift 5.5+, use actor for thread safety:



actor SettingsManager {    static let shared = SettingsManager()    private var settings: [String: String] = [:]        func setValue(_ value: String, forKey key: String) {        settings[key] = value    }        func getValue(forKey key: String) -> String? {        return settings[key]    }}


2. Factory Method

Defines an interface for creating objects, but allows subclasses to alter the type of objects that will be created. Perfect for creating different types of UI components or data models.



Example: creating buttons for different platforms

protocol Button {    func render()}

class iOSButton: Button { func render() { print("Rendering iOS button with rounded corners") }}

class macOSButton: Button { func render() { print("Rendering macOS button with gradient") }}

protocol ButtonFactory { func createButton() -> Button}

class iOSButtonFactory: ButtonFactory { func createButton() -> Button { return iOSButton() }}

class macOSButtonFactory: ButtonFactory { func createButton() -> Button { return macOSButton() }}

// Usagelet factory: ButtonFactory = iOSButtonFactory()let button = factory.createButton()button.render() // "Rendering iOS button with rounded corners"


3. Observer

Allows objects to subscribe to events and receive notifications about changes. In Swift, it's implemented through NotificationCenter, Combine, or didSet.



Implementation using Combine (iOS 13+)

import Combine

class WeatherStation { @Published var temperature: Double = 0.0 func updateTemperature(_ temp: Double) { temperature = temp }}

class WeatherDisplay { var subscriptions = Set<AnyCancellable>() let station = WeatherStation() func startObserving() { station.$temperature .sink { [weak self] newTemp in print("Temperature changed: \\(newTemp)°C") self?.updateUI(with: newTemp) } .store(in: &subscriptions) } private func updateUI(with temp: Double) { // Update interface }}


Classic implementation using protocol

protocol Observer: AnyObject {    func update(value: Int)}

class Subject { private var observers = [Observer]() func attach(_ observer: Observer) { observers.append(observer) } func detach(_ observer: Observer) { observers.removeAll { $0 === obs

Blogs

Book Recommendations