Coordinators Essential tutorial. Part II

Andrei Panov
Blacklane Engineering
4 min readApr 10, 2017

In the first part of this tutorial, I discussed coordinator’s approach in general and showed some common examples relative to my implementation. To be aligned with this article, please read the previous part.

In this part I want to cover some edge cases of coordinator usage.

I guess the most interesting parts will be:

  • AppDelegate configuration
  • managing launch options
  • deep links & push notification handling by coordinators

I’ll show step-by-step solutions with an explanation.

How to configure AppDelegate with main app coordinator?

AppDelegate becomes really simple since all navigation logic moves to AppCoordinator.

So, what you need to do is to create a Coordinator, inject rootController and call start().

We still need to implement delegate methods like didReceiveRemoteNotification or continueUserActivity in AppDelegate, but in the method’s body we just call the Coordinator start() again (we’ll send some data by this method, I’ll show it later in this tutorial). As a benefit we can cover the Coordinator’s logic by unit tests and keep AppDelegate clear.

Let’s introduce Instructor

Most parts of real production apps have different launch scenarios.

We want to introduce our app to the user by presenting a tutorial, showing an auth flow, informing them about new features, or simply displaying the main screen. We should manage this behaviour carefully.

Let’s imagine we have 3 different cases:

  • User should see onboarding tutorial (we show onboarding screen)
  • User should be logged in (we show login screen)
  • User has finished both previous steps and just sees the main screen

For an easy way to handle all of these scenarios, we create an enum as a coordinator’s helper. This enum should check all flags and return the correct scenario that the Coordinator should follow. I name this entity Instructor, as it is instructing the coordinator what to do next.

After creating, AppCoordinator can follow start function and run different flows depending on the state:

This approach is applicable for any coordinator. The code becomes clear and easy to read when flow logic is extracted in enum. Now let’s say we want to show the ItemCreation module, but after presenting and a server request, we receive an unauth error. How can we handle this error? The coordinator just checks instruction and runs auth flow. After finishing the coordinator asks Instructor again and then runs ItemCreation flow.

Deep Links, Push Notifications, Force Touch

I believe coordinator’s strength is working with deep links, push notifications, and Force Touch. I don’t want to cover entitlements and certificates stuff. Let’s say all of it works properly and we just need to handle logic. Nowadays, we have a lot of options when it comes to opening our apps: force touch, push notifications, deep link, or press the app’s icon (maybe a new one in the future, Apple? 🤓).

How to handle it? As you remember in the previous part, I told you about BaseCoordinator which contains the children coordinators array. All coordinators inherit it. It means that we can loop all children and perform actions. To achieve this, we just add a method that will handle DeepLink logic itself or loop children to find one who can handle it. It will be like a tree. And we can create specific protocol to achieve this goal.

Let’s update Coordinator protocol:

Now we’ll just add both methods with empty body to BaseCoordinator to keep it optional. Children can inherit one of these methods or both depending on our goals. In some cases, we can run default behavior by using start with no options, but if we proceed with the deep link scenario we should add information about presenting case. How to achieve it? A better way would be to add some entity to our project that contains all deep link shortcuts and create objects that we can send with start() methods.

Did you miss enums? Let’s add a new one! It will be DeepLinkOption:

As a benefit, all of our DeepLink methods in coordinators will be like switching for enum. Yes, same as Instructor on the previous example, you are correct.

We could add some additional build (with…) methods depending on our needs:

After this iteration, if we return back to AppDelegate and update it a bit, it will looks like this:

Ok, looks nice?🤔 Then you will receive a push notification or a deep link and you simply build your DeepLink and proceed with this action with AppCoordinator.

Conclusion

In every new solution that we try to implement in our code we are faced with a lot of edge cases and some not so beautiful solutions. It shouldn’t be like hype driven development, we just need to properly improve all tricky parts step by step.

If you have any questions or new specific problems, feel free to write me. And check Github repo with whole implementation.

--

--