How to handle with 173 copies of an app
Maintaining 173 apps from the same code is almost impossible. Almost impossible. Almost. So let’s try! 🤯
Sometimes developers need to create different applications with different branding, for different companies, even if they start from the same code.
Imagine creating a management and booking platform for hospitals. But major hospital brands, (The Mayo Clinic, Singapore General Hospital, for example) want their patients to use their own application.
(Yes, usually this kind of corporations have enough resources to create their own platforms, but this is only an example 🤨)
Creating these applications initially may not be difficult, the real problem is maintaining a solid structure to keep every one of them up to date.
Let’s assume that all these applications have the same requirements, but each one needs different
With these 173 emojis you can get used to the idea:
😀😁😂🤣😃😄😅😆😉😊😋😎😍😘🥰😗😙😚🙂🤗🤩🤔🤨😐😑😶🙄😏😣😥😮🤐😯😪😫😴😌😛😜😝🤤😒😓😔😕🙃🤑😲☹️🙁😖😞😟😤😢😭😦😧😨😩 🤯😬😰😱🥵🥶😳🤪😵😡😠🤬😷🤒🤕🤢🤮🤧😇🤠🤡🥳🥴🥺🤥🤫🤭🧐🤓😈 👿👹👺💀👻👽🤖💩😺😸😹😻😼😽🙀😿😾👶👧🧒👦👩🧑👨👵🧓👴👲👳♀️👳♂️ 🧕🧔👱♂️👱♀️👨🦰👩🦰👨🦱👩🦱👨🦲👩🦲👨🦳👩🦳🦸♀️🦸♂️🦹♀️🦹♂️👮♀️👮♂️👷♀️👷♂️💂♀️💂♂️🕵️♀️🕵️♂️👩⚕️👨⚕️👩🌾👨🌾👩🍳👨🍳 👩🎓👨🎓👩🎤👨🎤👩🏫👨🏫👩🏭👨🏭👩💻👨💻👩💼👨💼👩🔧👨🔧👩🔬👨🔬👩🎨👨🎨👩🚒👨🚒👩✈️👨✈️👩🚀
We must take in mind that it will not be 2 or 3 apps, if everything goes well it will be about 173 applications. 173 in Android and 173 in iOS.
(173 + 1) * 2 repositories
The first idea was the following. The base code is stored in a repository that serves as a submodule for different configuration repositories. Each of these is a project that launches the
ViewController with the corresponding configuration:
The code is developed on
AppCore, which is convenient, because the maintenance of this repository is simple. But every time you need to make an upload of all the applications you need a script like this:
git pull submodule
This structure has many problems:
- Let’s start by creating the repositories. We will need 1 for the AppCore and 173 for each app. Remember that since we are working on both platforms, all this is doubled.
(1 + 173) * 2 = 348repositories. 🤓
- This approach “requires” to have every repository downloaded if we want every update to be released quickly. If you are used to Android or iOS projects you will know that each project, and its compilations, takes up a lot of hard disk space. 😩
- The process of updating each application is really slow, cause each application requires many
- Each new version of
Xcodeusually requires changes in the project, so sometimes you have to make scripts that make changes in all the repositories to adapt them to the new versions. 🥴
2 Repositories with 173 + ~2 branches each
Trying to solve mainly the problems 1 and 2 of the previous system, we started looking for single-repository solutions. We thought that what before was a repository could now be a branch, so we designed something like that:
- ~2 branches for development;
develop. And all necessary branches like
- 173 branches with the
mastercontent customized for each app.
I mean, the
master code is the production code and each of the branches has a
master copy with the appropriate configuration for each app. This way, changes in
master are propagated in each production upload to each of the app branches. So you need a script like this:
git merge from master
This also solves point 4 above, since structural changes in the project are automatically propagated to each of the branches.
But this solution is still not perfect:
- Problem 3 remains: the update process is still very slow, each branch contains a “project version” so, in addition to being a huge repository, each branch contains a lot of information. 🥱
- If you have to make changes in every app configuration you need to write a script that goes through all the branches and makes the appropriate modifications. 🤭
A repository with a submodule with 173 branches
The previous problems left us with only one option, to find a solution that keeps its base code in only one repository (well, one for android and another for iOS). And the configuration is stored in an external repository. So we set up the following structure:
The repository works like a normal repository, containing an alternative
android flavour and
iOS scheme. This project is accompanied by a configuration submodule. This submodule contains 173 branches which store only the necessary info like
firebase configuration files, etc.
Then, we need a script for every app deploy:
git submodule checkout branch
merge config with project
It goes through the configuration branches and each one of them is integrated in the code to upload the application. By not having to make commits on each branch or pushes, the script is much faster and the repository can be kept clean of branches. 🥇
Git lets you create actions or run scripts when certain git actions happen. Using a
post-checkout hook, you can make the script run every time you change the configuration branch. This way you can test it at any time. 🤙
Things to keep in mind
Apple App Store Connect
Apple does not allow the publication of these “copies” in the same developer account. 🤨 You may encounter the following issues:
- Guideline 4.2.6: The solution to this problem is to create different developer accounts for each brand.
- Guideline 5.2: You must prove that you have the right to use the images and logos in the application. Attaching this information once should be enough.
Google Play Developer Console
At the time of writing this article, seems there is no problem in keeping all versions in the same developer account. But this may change at any time. 😉
It is a number high enough to understand the dimension of the solution and above all, it is a prime number, composed of prime numbers. 🤓
See you in the next post 👋