From an app to a Super App

Part 1: Organizing the app

Juantri Jiménez
Jeff Tech
Published in
5 min readMar 20, 2020

--

At Mr Jeff, we have experienced an important period of change during recent months. We are no longer Mr Jeff, now we are Jeff, a Super App that offers multiple services in more than 25 countries over 4 continents. We currently have three operational services: the well-known laundry service Mr Jeff, and the two new ones: Beauty Jeff and Fit Jeff.

This transformation has generated deep modifications of designs, styles and the appearance of new features in all the platforms on which we offer the services: mobile apps, web, tools for franchisees, etc. In the following article, we will focus on the processes performed to adapt all these changes in the iOS application, the problems and challenges that we encountered during development and how we solved them.

Introduction

Our application is based on the MVVM architecture with routers. The Router is responsible for navigating and initializing the controller. The organization of the folders is based on functionalities - that is, if for example we talk about coupons, we can list the coupons, create, see the detail, etc., which leaves us with a hierarchy of folders such as the following:

Coupons folder structure

Within each folder you will find all the view data: xib, controller, view model and router. Many developers prefer to organize them by the type of file: controls, view models, etc., but each development team decides which setup is better according to their project and in our case, we decided that this structure helps us to maintain a clean and clear project, which in turn helps teamwork and avoids conflicts during the development process.

User Coupons folder structure

Because of all those changes, we found some problems we had to deal with:

  • The app was not prepared for dealing with different services or businesses: laundry, beauty, fit, and more to come.
  • Folder structure does not differentiate between business model: views, models and data providers were together without differentiation between the business models and the common part.
  • We had too many “utils” and “helpers” folders where we were placing all common parts, generic classes and too much code.
  • Data models were repeated.

What we need and why?

We need:

  • To control and develop the current business models and the new ones easily.
  • Create a simple folder architecture to deal with the different views, models and data providers from each business model.
  • Refactor generic classes so that the functionalities are organized in folders with similar logic.
  • Unify repeated data models for working on the app with the same model.
  • Delete deprecated code.

What we obtain with that?

  • Avoid conflicts between colleagues when working.
  • Delete “warehouse” folders.
  • Improve the app structure for future development.
  • Organize functionalities and delete repeated or deprecated code.
  • Obtain a clear, simple and easily maintainable code.

How did we do that?

Relocating files

The first thing was to relocate the files according to the service or business model to which they belong, or if they were common throughout the App, so the Use Cases and Models folders now are as follows:

Use Cases folder structure

Through this relocation, we realized that we had data models that were basically the same, so we unified them them to work throughout the application with the same model and thus avoiding confusion.

Some Providers Data Models examples
Final Provider Data Model

On the other hand, data providers are now organized in two folders: User Defaults and Network Providers. Inside the Network Providers folder, we maintain the same structure as with models, separated by our microservices, Firebase and the rest of the API services that we use.

Providers Data folder structure

Setting the generic classes

Continuing the refactor, the next step was to clean the “Utils” and “Helpers” folders, regularly used like warehouse folders for common things, where we had all kinds of code and methods that do not share logic between them, therefore generating very long classes.

To solve the problem, we analyzed all the existing methods and classes to create a folder structure that really describes the actions of those methods: Config, Services, Validators, Formatters, Exceptions, etc. Because of these folders, we can now know the real functionality of our code and where it should be. With the new structure, we separate logics and methods into independent classes and delete those “Helpers” classes.

From Helpers to an organized folder structure

An example of a validator:

Developing the App core

Finally, we modified the user session class, a class where we have all the information about the user during the use of the app. Now we have more business models, the session has to manage different information about each of them, for example getting only the hub of the laundry service. To refactor this class, we created a wrapper where we redirect to the old session or the new one when the app calls it to get the information. Using this system, we can change the class step by step with the new implementations.

A process that has helped us to make all this change has been to have a good test coverage of the app’s functionalities. For example we checked with tests that the storage of the information of a service or the user and its subsequent recovery were correct. After that, and together with the wrapper, we launched these tests against the new user session to check the new logic developed. In this way we ensured that the changes made and the new classes created continued passing the tests.

What’s next?

So far the first phase of refactoring our project is complete, but it does not end there. Our next goal is to create modules in the project to separate common functionalities, vertical business, etc. In this way we will improve the performance of the App in terms of compilation times and will improve the process of development and reuse of code. In the next article, we will explain how to create a project with modules, developing an example project.

--

--

Juantri Jiménez
Jeff Tech

Spanish iOS software engineer. I write about features of Swift and iOS development practices