Killing the Mobile Apps Beast!

How to divide a big iOS and Android projects to modules and shared packages.

Yusuf Meimeh
Digital Cloud
3 min readJan 2, 2019

--

Players: Yusuf Meimeh (iOS) and Abdullah Hussein (Android).

Level: 70+ Screens in 15+ Modules Mobile App Beast.

Background:
Beast: You enjoyed feed me in the previous six months? I’m feeling satiety and cannot eat more! I will eat you and your productivity.

Mission: Figure out the best way to divide the app into smaller decoupled yet integrated parts.

In this article, we will share our experience to pass this level, and we hope you enjoy our path and share your thoughts with us. One of the most significant problems we face is the inverse relationship between the app grow and our productivity especially when we need to enhance the previous module.

The app was delivered to us after a long failure with other companies and the product owner needs to build a new version from scratch as fast as possible, so we started with the straightforward approach and developed it as a single app. It is difficult to imagine how big the product will be so we built it in a single app.

After the first release, the client started to add new features, and the app became bigger and bigger. Therefore, we began to lose control and face many difficulties when updating any existing features which have led to testing all related features again to guarantee everything is ok.

Delivery time, bug fixing effort, building, debugging and running the app in Simulator or real device, all affected and increased over time, and sometimes it is very complicated even to disable, delete or delay the release of some modification to a later stage!

The Solution

As an iOS developer, you may be familiar with a project with one or two targets if you use Pods. On the other hand, we start our Android projects with a single module.

We explore many separations of concerns methods, some of them end with a layered application, e.g., Presentation, Domain, and Data layer. However, we need more level up to deal with modules, not layers. So, we start splitting the app into smaller blocks:

  • App: register a list of modules and initialize them.
  • Modules: represent a single module in the app.
    (e.g., Auth, Setting, Events, News, etc.).
  • Packages: common cross features and app features.
    (e.g., UI views, network helpers and others).

These blocks can be developed independently, but smoothly integrated and work with each other. While we have an already existing application, we take an incremental approach by leaving the main application as it is, and incrementally decouple its modules and packages one by one.

By decoupled feature module, we meant the complete responsibility of the feature including but not limited to the Presentation layer, Models, Notification handling, Menu items, and 3rd Party libraries.

While focusing on modularity and decoupling, this approach can simplify the reusability of these modules into other apps. Another not planned advantages are the ability to develop each feature with its architecture, and SDK version.

To achieve the dynamic modules loader, we start our Service Provider Pattern implementation, all of our modules must implement an interface so it can be loaded, initialized, and perform some actions like notification handling and menu items.

We currently experiment some refinements like IoC container, Event-driven modules communication, Kotlin multi-platform library, and we expect to get back to you soon with some templates and packages.

--

--