Introduction to iOS Coordinator pattern

vijay sn
5 min readFeb 21, 2022

In our application, We deal with a lot of screens (view controllers) for serving business solutions. We might have used it with the combination of different architectural patterns — MVC, MVVM, and VIPER.

Have you ever checked how the coupling is between any two View Controllers presented/pushed over one another? Let's look into that in detail.

What are we solving?

This is usually how we will call one view controller from another view controller.

The problem with this approach is One view controller must know about to create, configure, and present another view controller making it more tightly coupled, non-isolated and dependent.

By using the Coordinator pattern, we can abstract the navigation flow from View Controllers thus making them more manageable, reusable, and testable. This will also give us to change the flow of the application easily based on our growing business needs.

What is a Coordinator Pattern?

Coordinator pattern provides an encapsulation of navigation logic. Instead of pushing and presenting your ViewControllers from other view controllers. All the screens navigation will be managed by coordinators.

Coordinator Pattern

This is how View Controllers are isolated and independent of each other. In this pattern, the Coordinator presents/displays the view controller which gets control back using Delegate Reference Methods. We will be using protocols for Communication.

Let's take a look at this basic example of creating a Coordinator.

This is how the basic Coordinator is built upon using navigationController reference and start method to initialize the Coordinator.

We are maintaining the Child Coordinators array to have a track of what are all the other coordinators that got connected. It will help us to manage the responsibilities of the module gracefully.

For Example, I can group and manage the navigation of the Authentication Module — which contains Login, Sign Up, Verification, etc. Where I can Manage Authentication Child Coordinators easily. It will definitely help in managing a big application with multiple modules.

Creating a Coordinator

Let's create/rename the view controller to Login for Instance.
For Every View Controller, We can maintain a Coordinator to control the navigation. We will be making use of Coordinator Protocol to create Coordinators for the application flow.

In the above example, we are Initialising the Navigation Controller for the Coordinator which pushes View Controller on the Navigation Stack. Start Method initializes the view controller and pushes the same to the Navigation Controller Stack.

Setting up the Initial Coordinator of the App

For Setting the Initial Coordinator, We are creating a Utility called App Router which will take care of all high-level routing inside the application.

setRootViewController() method sets up the Login Coordinator which will be set as the root view of the app. We need to trigger the setup from Scene Delegate — Connection.

Now run the app. You can observe that we have set the root view for the app using Coordinator.

App Flow

Now, we are going to take a real-world example to explore navigation using the Coordinator pattern.

Let’s take a Login View basically the entry view of the app. On successful login, the user will be navigated to the dashboard. Users can explore various options in the dashboard in which the profile page is one of the options.

On the profile page, the User can see the Profile Information and can log out of the application.

App Flow is given as a simple flow diagram below:

App Flow

Here we will be exploring how coordinators will be useful for

  • Forward Navigation
  • Backward Navigation

Forward Navigation

Let's look into how the Coordinators are used for Forward App Navigation from One View Controller to another View Controller.

We are using the Delegate pattern for facilitating the communication between the Coordinator and View Controller.

Once the delegate method is triggered, the conformed method in Coordinator will get triggered for navigation to the next View Controller.

See how abstract and easy the navigation using the Coordinator. Here you can observe the real purpose of the Coordinator pattern which is abstracting the layer of navigation from the View Controller.

View Controller will not be aware of what View Controller it is going to present/push thus making Navigation Logic isolated from View Controller.

Backward Navigation

We will be using a common protocol for View Controller to pop it from the stack.

With respect to the flow that we have mentioned in the diagram included above. We are going to take Profile View for example and see how the backward navigation works with the Coordinator.

Here we can observe, we have two IBAction methods one to go back to Dashboard and one to log out of the application.

As soon as the delegate method got triggered, we will get the control in Profile Coordinator for the navigation.

By Triggering the delegate for BackToPreviousViewControllerDelegate, the Control goes back to its previous coordinator which is DashboardCoordinator.

In Dashboard Coordinator, the navigation controller will be popped up to root if the User logs out and remove the last view controller for going back to the previous view controller.

Conclusion

Hope you have understood how Coordinators work and how the navigation flows with the help of the Coordinator pattern.

One of the most common problems in adapting and practicing the new architectural pattern is consistency and maintaining good practices.

I would always suggest we can create Xcode templates which will reduce the time and help us in maintaining the code base gracefully.

Happy Learning :)

You can find the source for this project in this Git Hub link — https://github.com/vijaysn02/iOS-Coordinator-Sample

Let's connect through LinkedIn:

My Other Blogs

--

--