Discover the Coordinator Pattern


You’re more of a video kind of person? I’ve got you covered! Here’s a video with the same content than this article 🍿


You’ve heard of the Coordinator Pattern, but you’re not entirely sure how it works? 🤨

Don’t worry! I’ve got you covered! 😌

In just a few paragraphs we’ll go over everything you need to know to understand how this pattern works!

Let’s start with this ViewController:

When a user selects a movie in a list of movies, this ViewController is responsible for navigating to the details of that movie 📲

But this approach doesn’t scale very well 😔

For instance, it would be difficult to implement a deep link that programmatically navigates to the details of a movie...

And that’s why it makes sense to extract the navigation logic to a new object called a Coordinator!

So let’s do it in 5 easy steps 🔥

Step 1️⃣, we create the Coordinator:

Step 2️⃣, we extract the navigation logic to the Coordinator:

Step 3️⃣, the ViewController stores a weak reference to the Coordinator:

Step 4️⃣, we use this reference to inject the Coordinator into the ViewController:

Step 5️⃣, the ViewController can now rely on the Coordinator to perform the navigation logic:

And that’s it: we’ve successfully implemented the Coordinator Pattern 🥳

Now other parts of our app can also rely on the Coordinator: for instance our AppDelegate could trigger a navigation in response to receiving a push notification 👌

Here’s the code if you want to experiment with it!

class MoviesViewController: UIViewController {

    weak var coordinator: Coordinator?

}

extension MoviesViewController: UITableViewDelegate {

    func tableView(_ tableView: UITableView, 
                   didSelectRowAt indexPath: IndexPath) {
        let movie = movies[indexPath.row]

        coordinator?.showDetails(of: movie)

        tableView.deselectRow(at: indexPath, animated: true)
    }

}

class Coordinator {

    var navigationController = UINavigationController()

    func startCoordinator() {
        let initialViewController = UIStoryboard(name: "Main", bundle: nil)
            .instantiateViewController(withIdentifier: "Movies")
            as! MoviesViewController
        initialViewController.coordinator = self
        navigationController.pushViewController(initialViewController,
                                                animated: false)
    }

    func showDetails(of movie: Movie) {
        let detailsVC = UIStoryboard(name: "Main", bundle: nil)
            .instantiateViewController(withIdentifier: "MovieDetails")
            as! MovieDetailsViewController
        detailsVC.movie = movie
        navigationController.pushViewController(detailsVC,
                                                animated: true)
    }

}
Previous
Previous

Discover the MVP Architecture

Next
Next

Discover Dependency Injection