MVVM + FlowControllers -Part 2

Vinayak Srivastava
VMware 360
Published in
6 min readJun 30, 2021

Architecture strategy for iOS app development

For the understanding of working of MVVM and the existing design flaws when using MVC please refer to the Part 1 of this series —

MVVM + FlowControllers -Part 1

Now that we have understand the working of MVVM in an iOS application, let’s look at the other part of the architecture called FlowControllers.

FlowControllers

When it comes to the UI navigation in iOS, Storyboard is the choice for all developers irrespective of the architectural pattern in use. Storyboard provides a powerful tool to structure UI, manage and provide navigational setting in the form of ‘Segue’.

It’s quite common to see ‘performing’ and ‘unwinding’ Segues for all the navigation between ViewControllers.

While this might seem a good solution initially, it has few issues with the overall architecture of the project.

Let’s look at the issues with this approach —

  1. It adds unnecessary dependencies on one ViewController to be aware of the navigation logic.
  2. Moreover, the configuration work is done in the process of performing this segue. This is an overhead on the ViewController pushing the other ViewController. This is directly in violation of ‘Separation of Concerns’.
  3. As the project progresses, the number of ViewControllers increases and so does the navigational complexity in the Storyboard. It soon becomes difficult to read in the Storyboard where the segues are headed in the mess of spaghetti wirings of these segues.
  4. This also leads to the poor reusability of these ViewControllers and makes the UI Unit testing complex.

So how can we solve this — one approach is by using FlowControllers.

FlowControllers is an architecture pattern, which strives to solve this. It’s also known by other names like FlowCoordinator and AppCoordinator. Irrespective of the name, its functionality is the same. It’s a simple object to manage the control flow of the app. It configures and coordinates each screen for presenting it.

A FlowController should have the following salient features -

  • Each app should have a minimum of one FlowController.
  • AppDelegate owns the FlowController.
  • Each MVVM unit doesn’t know/care about other MVVM units.
  • Each MVVM unit defines interface for their actions. FlowController listens to these interfaces and handles the flow between the screen of the app.
  • Each FlowController has ‘Configuration’ and ‘Navigation’ knowledge of the app.

Let’s look in its inner working:

Let’s assume an app has a Login, Home and Profile module as shown in the above fig. The FlowController will manage the navigational responsibilities in following steps -

  1. On the first launch FlowController will configure and present the Login module.
  2. Login module will then notify the FlowController about the outcome of its task (i.e. login successful or failed in this case).
  3. It’s the job of FlowController to determine based on app’s business logic where to go next. In this case, it would be the Home module.
  4. So, the FlowController will then configure and present the Home module while popping the Login module out of the navigational stack.
  5. It would continue the same way for the other modules.
  6. Suppose the Profile module has two functionalities — to show and modify the profile screen and image. The advantage of using FlowController is that it can configure the Profile module based on the requirement and then present it to do exactly that part of the job. Note that the Profile module remains completely aware of which module invoked it and where to go next. FlowCoordinator will swiftly manage that, once the Profile module notifies it of the task completion.
  7. This follows the ‘Segregation of Concerns’ principle and removes the spaghetti of segues in the Storyboard. No ViewController knows about the navigation to another one.

NOTE — for the purpose of brevity, a simpler example was used. In a real app development process, there are bound to be multiple such modules and independent instances of MVVM structures to be used. It becomes clearer when we look at the next section for getting a complete picture of this.

MVVM with FlowControllers

When we combine the MVVM and FlowControllers architecture together, this is what the grand design of the application strategy looks like:

Note that at this level of abstraction, the MVVM units and FlowController are having all the internal design as we discussed above.

The AppDelegate is holding the ownership of FlowController as we discussed in previous section. This is because AppDelegate will exist throughout the lifecycle of the application, whereas MVVM units will come and go as per the app’s navigation logic.

An app can have multiple MVVM units for different modules (e.g. Login, HomeScreen, Settings, and Profile). Each of these MVVM units have their own business logic and implementations and are completely devoid of the knowledge of existence of other modules. Their SPOC (single point of contact) will be the FlowController, which will in turn handle the navigation between different modules and different screen effectively. This navigation logic will not be exposed to MVVM units.

At this birds-eye view we can see that ‘Single Responsibility’ and ‘Separation of Concerns’ principles are preserved here. These principles percolate down to the very basic units of this design as we peek inside each unit of the above design.

With this architecture strategy we see the following notable benefits:

  1. Each screen and module are now truly independent.
  2. There is no more spaghetti code to manage the navigation between screens. We can get rid of all the Segues in storyboard, which makes it clearer and easier to understand.
  3. Follows ‘Single Responsibility’ and ‘Separation of Concerns’ principles.
  4. Increased testability of ViewModels due to separation of view lifecycle and navigation business logic.
  5. Highly reusable components in each module.

With this we can now say that we were able to solve a great deal of shortcomings in architecture using MVC with Cocoa Touch framework. MVVM with FlowControllers is more robust, easy to use and unit test architecture pattern for iOS application.

Advantages of MVVM with FlowControllers architecture

MVVM with FlowController architecture not only solves the existing issues with the typical MVC designed iOS apps, but also provides a solid foundation for building iOS apps which simplifies the complexity in the presentation management and makes the architecture scalable for handling more complex flows.

Below is a list of what we learned so far and why this architecture can be the game changer when it comes to designing complex iOS apps

  1. Unit tests — The MVVM enables us to easily setup unit tests for the business logic of the app without the dependency of the View’s lifecycle. Since each screen and module are independent with this design, isolating a test setup is considerably less cumbersome. This will also facilitate a better environment for a Test-Driven-Development of the application.
  2. UI Tests — With the FlowController taking care of all the flows and navigational responsibilities of the app, this is a better setup for quickly scaling up the UI tests as well.
  3. Highly scalable and modular code — As a result of using this architecture, we get to follow the ‘Single Responsibility’ and ‘Separation of Concerns’ principles which highly difficult to achieve in the default MVC setup of the app as discussed earlier.
  4. Easy to debug — The ‘Separation of Concerns’ principle being utilized in a better way galvanizes the debugging process as the developer will know exactly where to look at when handling bugs or troubleshooting.
  5. Simplifies the Code Review process — As this architecture does an excellent job of putting code structures in the right place with the simple understanding of Model-View-ViewModel, it reduces the time it takes to review a Pull Request consisting of large number of files. As the responsibility of each module is designed to be agnostic of other views in the app, it makes the intent of every file in the MVVM + FlowController setup very clear and specific of its duties and what the code structure might entail.

Sample App — This article comes with a sample app build using the Xcode template mentioned above. This will act as a reference point when developing new modules in your app as well as when we’re looking into converting an existing application to follow this architecture.

Link to the sample app -

--

--