At the core of the application lies the DrinkService
protocol that has only one function – getDrinks(completion:)
.
The idea to program against this interface gives more flexibility and maintainability to the Client.
Now you can use anybody who implements this protocol without knowing its concrete type.
Meaning you can easily extend the app by adding cache, some other drink brewing service implementation, etc.
For now only RemoteDrinkService
implements DrinkService
.
All of those classes are bundled in the DrinkService macOS framework, so you can develop and test it super fast (because you don't need to launch the simulator every time). But how can it run on iOS and use in my app then? Choose DrinkService target, go to Build Setting and observe iOS macOS under Supported Platforms. By default, only macOS is there, so I had to extend it manually. DrinkService is a Static Library, meaning you don't have to embed it in your application.
DrinkBrewingFlow
is a separate object that handles navigation. This way, a ViewController is decoupled from creating other controllers and pushing them onto the navigation stack. This design lets us change the brewing flow easily. Want to present Extras before Sizes? Just create a new flow with the changed steps, and a ViewController remains intact.
It opens the possibility to experiment with the order + A/B testing.
The main and only (except some helper controllers) player is ItemListVC
. Drink, size, and extra are basically just items and can be presented in a generic way.
How does ItemListVC
plays out with DrinkBrewingFlow
. It has a set of closures onViewDidLoad, onDidSelectRow, onDidDeselectRow
that are assigned during the flow creation and triggered with according events.
If there are no Extras, this step is skipped, and the User proceeds to the Overview screen.
There are custom animations of presenting and hiding Extra options. Brew button on the Overview screen also has a custom animation.
Neither the DrinkService module nor the UI module don't depend on each other. All of the classes instantiated and composed inside the Composition Root.
There is feature/refactoring branch.
It has a much cleaner UI design (I compose views instead of having constraints logic), although not finished. I use iOS14 APIs UIContentView
and UIContentConfiguration
.
It was fun to refactor (I certainly liked how my code UI improved), but due to the lack of time and first acquaintance with those APIs, I decided to roll back and finish what I started.
In this project I used GitFlow.
I hope you'll like what you'll see in my project. Have a good day!