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)
    }
} 
             
             
             
             
             
            