Flow Coordinators Using Swift

Handle Dependencies well!

Image for post
Image for post
Image by Mesh

Before we start

Difficulty: Beginner | Easy | Normal | Challenging
This article has been developed using Xcode 12.2, and Swift 5.3

Requires iOS13 and above for the implementation used to lock the view. The Repo is avaliable for download.

Prerequisites:

* You will be expected to be aware how to make a Single View Application in Swift.
* I have taken a programmatic approach to the interface, although this is unlikely to trip you up the guide is here
* This article uses Behaviour View Controllers
* This article uses my Network Library implementation

Keywords and Terminology:

Architecture: The base structure of a software development project UIViewController: A view controller is an intermediary between the views it manages and the data of your app

This project
The motivation

I’ve previously covered the use of coordinators with MVVM and while that isn’t required reading for this project, having a look at the repo would give you some idea as to the level of this article, and the motivation for writing it.

Although I am proud of that project structure, it can be challenging to keep the coordinators in sync with the view controller hierarchy

This article is intended to leverage the MVVM-C architecture, and also provide a sample as to how the solution might be tested!

The frameworks used

In order to keep this article, and the code as readable as possible I’ve used my own Network Library and Two Way Binding Library, and the links shown here allow you to look at my detailed explaination in those articles.

The idea

The project here has a login screen (which you’ll need the username-password combination of eve.holt@reqres.in-cityslicka (provided by https://reqres.in/api/login) and once logged in there is a UITableView instance holding the data from https://jsonplaceholder.typicode.com/posts and then a detail view that shows the same String.

The example diagram is shown here:

Image for post
Image for post

Where we transition from the left-hand view controller to the right-hand side of the diagram. The UIViewController instances are called LoginViewController, ToDoListViewController and DetailViewController (in order from the diagram).

Since the project implements MVVM two-way binding has been implemented, and the data is stored in the ViewModel for each of these UIViewController instances which are called LoginViewModel, ToDoViewModel and DetailViewModel (again in order).

Image for post
Image for post

Concepts

Encode Behaviors into Reusable View Controllers Dependency injection Data Binding using my Two Way Binding Library avoiding the use of third-party libraries Key Chain URLs are build using my URL Builder The views here are programatically created.

Using the project

If you want to download the project from the Repo to get all of the code, you are welcome to. However since the login server is provided by https://reqres.in/api/login to log in you need to use a username of eve.holt@reqres.in, and a password of cityslicka.

The token is stored from the login, and then is not used for future API requests. This is a function of using free API calls, and if you were to replace the API calls used it would be possible to retreive it using UserDataManager().token / keychain.tokenand then use it in the client API for AnyNetworkManager.

Limitations

I’m using a programmatic way of creating the UIViewController instances, and have not attempted to demonstrate how to use a UIStoryboard in this project, although an approach from [this article covering MVVM Dependency Injection using Storyboards](Dependency Injection using Storyboards) could be adapted.

This is a demo project, and does not even attempt to obtain 100% test coverage, rather it covers the majority of areas and how they might be tested through a variety of test strategies.

Of note in the Implementation

The Errors

In relevant view models we have an errorBindable defined as:

which is observed from the relevant UIViewController instance to a property, and the UIAlertView is opened from there.

This calls an extension that allows for a completion handler to communicate back to the UIViewController instance that the user has finished with the UIAlertController.

Initializers

In terms of dependency injection, a good use of initializers in the view model instances mean that the network manager and keychain manager can be used, and swapped out for mocks during testing (providing the mocks conform to NetworkManagerProtocol and UserDataManagerProtocol respectively.

Then within tests a Mock can be used and injected using something like the following:

A sample UIViewController and accompanying view model

The login process is split between LoginViewController and LoginViewModel, as detailled here:

Whereas the LoginViewModel makes the network request, and is bound to the UIViewController instance:

The structure of the ProjectCoordinator

The project coordinator is described through the following project chart

Image for post
Image for post

If you look through the repo I really think you’ll see how this functions, and perhaps how this can work in your own working context.

Good luck!

Conclusion

Flow Coordinators are a great way to prevent the classing “massive view controller” that we have all read about, while making sure that we have full functionality to aid understanding.

Remember you can download the Repo to get all of the code and, hopefully find this project useful for whatever you are doing in your coding journey.

Whatever you do with this project, and your time coding remember to do please enjoy it!

If you’ve any questions, comments or suggestions please hit me up on Twitter

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store