The Coordinator Pattern
Centralize navigation flow logic.
The Coordinator Pattern is a free Swift Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Swift Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
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.
Frequently asked questions
Is the “The Coordinator Pattern” lesson free?
Yes — the full text of “The Coordinator Pattern” is free to read here on the web, and the Swift Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Swift Academy course, upgrade to CoddyKit PRO.
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; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
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