How to make your iOS app reuse navigation logic. Rethinking the Implementation of the iOS Common Coordinator

In this article, we’ll review what a formatter is, one of the most popular methods to implement it, what the problems are with it, and what we can do about it.
Coordinator
A class that defines rules about how and when screen transitions should be performed by interacting with various inputs such as callbacks, notifications, etc.
Imagine you have these screens used to display your news feed and create a new post:NewsfeedViewController
And CreateNewPostViewController
And EditPostContentSettings
In the usual MVC fashion, you will likely have transitions defined as:
Let’s go through the above code step by step.
#1
Methode is preparation CreateNewPostViewController
When the user decides to add a new post and is responsible for viewing.
#2
How to deal with setup EditPostContentSettingsViewController
When a user wants to change their new content preferences, including when a post is automatically destroyed and also whether or not it is publicly available.
In the above approach, each view controller knows:
- What class is required to handle the requested user action
- How to set up another display controller to be presented
- What is the current rendering context (the current page is rendered modularly or in the navigation package)
- How to present another view controller based on the context of the current presentation
- How to handle other view controller callbacks or output data (screen or user flow result)
All of the above have the following negative aspects:
- Tight coupling between view controllers (each monitor knows about its own presentation controller or in some cases worse – the opposite direction where the child stream knows about the current parent)
- Display controls just got bigger
Coordinators are designed to help us with that. Let’s review the main benefits:
- Responsible for moving to another screen and any necessary setting as a result reduces the display controllers icon size
- Navigation icon can be reused if the same screen is rendered from different view controllers within the streamer
- Easier to write unit tests. Just run a callback with the required data and check how the navigation package looks after
- It helps to clearly define the scope of the display controller’s purpose and output. The output can be the user’s intent to create/edit/delete/view the action that results in the transition to another screen
Let’s rephrase the code above and see if the transition logic is broken now:
In the above code, we do the following:
- Select the moderator who delivers the news feed and initiates any children’s streams or offers other screens included in the current stream
- Handle the user’s intent to open the screen to create a new news feed post
- Select another coordinator that handles the creation of the new post in the same way as the previous one, and initiates any child streams or presents other screens included in the current stream
- Process user action with additional parameters in order to present a screen that is part of the new post flow
The nice thing is that you can only start introducing the coordinators to your project gradually.
One of the main differences with the sample code above and the most common implementation that you can find on the Internet is the compatibility with the protocol such as:
The disadvantage of the above solution is that the moderators represent their hierarchy separately from the set of windows consisting of view controllers and views.
Continuing to refer to children when we need to provide the flow of the child also requires us to issue this reference which is not always straightforward.
An example would flow into those cases where the root screen can be dismissed only by swiping down the half-modal screen, or if the sub-coordinator is sharing the app root console and the user decides to go back using a swipe from the edge of the screen, or another part of the app decides to change the currently displayed screen It forgets to de-allocate all resources belonging to the current context as the coordinator.
This results in a memory leak at best, and in some cases where service layer event listeners are used, the screen provided by the already unused formatter is changed.
With that in mind, it’s best to let the submitter hierarchy take ownership of the moderators they submit by referencing them aggressively in the callbacks.
with regard to start()
method, it usually doesn’t provide enough flexibility to cover all the attributes that can be passed in there, the presence of generics in some cases leads to the need to use write erase which you will also have to write unless you really need it, better to start with the initial formatter class Don’t match and build what’s needed based on your project needs.
Other areas in which coordinators can help are:
- Deep linking and handling of push notifications
- Screen transitions based on service layer events (notification / KVO / HTTP request results for network polling / update from Web Socket)
- The module tests screen transitions by confirming that there is a high-level window view/monitor within the navigation console or the provided model stack.
Of course, with these benefits, we can also list some downsides including:
- Introducing the development team to the new style is not an easy task and takes time
- Switching to a streams/events/screen-output mentality is difficult and not always straightforward
- For proper formatter memory management we need consistent use of weak references within view controller result callbacks. The point is that the formatter is referenced with a strong reference and the view controller should only be weak
In short, formatters are a great way to scale a project to a lot of screens and have a clearer definition of what features the app supports and how to transition between them within the app.
It comes with benefits like easier testing, code reuse, and better code separation. It does not require you to completely rewrite the application to use the new concept and new streams can be started easily.
This should give you enough reasons to consider using it and see if it would better suit the offered screen management solution that you may already have.
Do you think it could be suitable for your application? If you would like to participate please let me know why it would be a good idea or not, we can discuss it together further.