The Coordinator Pattern
Centralize navigation flow logic.
The Coordinator Pattern is a free Swift Academy lesson on CoddyKit. This is lesson 3 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Swift Academy learning path, and your progress syncs across the web and the CoddyKit app. The Swift Academy course includes 4 lessons in total.
The Navigation Problem
When views push and present other views directly, navigation logic gets scattered across the app. Each screen has to know about the next screen, creating tight coupling.
The Coordinator pattern solves this by extracting navigation into dedicated objects.
What Is a Coordinator?
A Coordinator is an object whose single job is to manage navigation flow. It decides which screen comes next and creates the view controllers or views to show.
Views become dumb about routing — they just signal events, and the Coordinator decides what to do.
The Coordinator Protocol
Most implementations start with a small protocol that every Coordinator conforms to.
protocol Coordinator: AnyObject {
var childCoordinators: [Coordinator] { get set }
func start()
}A Concrete Coordinator
A concrete Coordinator owns a navigation controller and builds the first screen in start().
final class AppCoordinator: Coordinator {
var childCoordinators: [Coordinator] = []
let navigationController: UINavigationController
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
let vc = HomeViewController()
navigationController.setViewControllers([vc], animated: false)
}
}Decoupling Views from Routing
The key benefit: a view no longer constructs the next screen. Instead it tells its Coordinator that an event happened, and the Coordinator routes.
This means a screen can be reused in different flows without changing its code.
Signaling Events Up
Views communicate with their Coordinator via a delegate or closure. The view does not know where it leads next.
protocol HomeViewControllerDelegate: AnyObject {
func homeDidSelectProfile()
}
final class HomeViewController: UIViewController {
weak var delegate: HomeViewControllerDelegate?
func profileTapped() {
delegate?.homeDidSelectProfile()
}
}Handling the Route
The Coordinator conforms to the delegate and decides how to navigate when the event fires.
extension AppCoordinator: HomeViewControllerDelegate {
func homeDidSelectProfile() {
let profile = ProfileViewController()
navigationController.pushViewController(profile, animated: true)
}
}Child Coordinators
Large flows (onboarding, checkout) get their own child coordinators. The parent starts a child and retains it in childCoordinators so it stays alive.
func startOnboarding() {
let child = OnboardingCoordinator(navigationController: navigationController)
childCoordinators.append(child)
child.start()
}Avoiding Memory Leaks
Because the parent retains children, you must remove a child when its flow ends, or it will leak. A common approach is a finish callback.
func childDidFinish(_ child: Coordinator) {
childCoordinators.removeAll { $0 === child }
}Coordinators with SwiftUI
In SwiftUI, Coordinators often drive a NavigationStack path. The Coordinator owns an observable path, and views append routes to it.
final class Router: ObservableObject {
@Published var path: [Route] = []
func push(_ route: Route) {
path.append(route)
}
}
enum Route: Hashable { case profile, settings }Benefits Recap
The Coordinator pattern gives you:
- Reusable views that do not hardcode navigation
- Centralized flow logic that is easy to change
- Testable routing separated from UI
- Composable flows via child coordinators
Quick Check
Test your understanding of Coordinators.
Recap
You learned the Coordinator pattern:
- Coordinators own navigation, keeping views routing-agnostic
- Views signal events up via delegates or closures
- Child coordinators model self-contained flows
- Remove children when flows finish to avoid leaks
Combined with MVVM, Coordinators complete a clean, testable architecture.
Learn Swift with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 122
- Lessons
- 409
Frequently Asked Questions
Is the “The Coordinator Pattern” lesson free?
Yes — any 3 lessons of the Swift Academy learning path, including “The Coordinator Pattern”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Swift Academy course includes 4 lessons in total.
What will I learn in “The Coordinator Pattern”?
Centralize navigation flow logic. You practise Swift Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Swift Academy?
No prior experience is required. Swift Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 4.
How long does the “The Coordinator Pattern” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Swift Academy lesson?
Yes. Every Swift Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- The MVVM Pattern
- Binding View Models to Views
- The Coordinator Pattern
- Testing View Models