The ProblemThe application consisted of two native mobile application codebases: one for Android and one for iOS. When we started, over time the codebase had become unmaintainable. There were a few very large “God Classes” consisting of large methods. Most of the functionality was built into these. Modifying and maintaining them had become a real challenge. The iOS and Android apps were essentially duplicates – same functionality but different codebases. The android app’s latest code base wasn’t up to date with iOS app features. Only the iOS app was launched, but android app was under construction yet. Components were tightly coupled. That kept bringing down productivity every time a few changes were made. Change often resulted in other parts breaking. At that time, a major requirement change was discovered that reduced the need for native code. Essentially, interacting directly with the phone’s internals became less important. The change was very high impact; so, we dedicated time to it. We wanted to build the app with the right stack and make improvements with all the learnings. It was clear that the existing stack would not serve the purpose. It would be better to rewrite the code from scratch and build from the right foundation.
Weighing the alternativesWe explored several latest technologies in detail to see how each would suit our app. We were trying to reduce the amount of code changes needed for the change and see if part of the code could be retained. We ranked the alternatives on the basis of four factors 1. Ease of development – size and complexity 2. Performance impact on the app 3. Ease of code maintenance 4. Impact on the current architecture It was interesting to explore what was out there for us to use. We explored a lot. We were confident that this exercise would yield benefits very soon. We discovered multiple technologies that addressed pain points in a unique way and kept analyzing which approach was the best for us. This led us to choosing the right stack.
2. Rewrite existing code in JS
Next we had to rewrite all the existing code from native to js. With the move to go native, we were questioning the need to write all the syncing ourselves. We tried to find alternatives to syncing and discovered firebase. Another BIG win for us was solving the challenge of publisher / subscriber system. The time required to learn FB paid back really quickly. NoSQL was not so much of a constraint for design as our data was already very flat in nature.
3. Model the app as a Single Page Application (SPA)
We felt that our app could be modeled very nicely as an SPA. We could show the different screens as states of the app and then reuse parts of the app as sub-states. This would allow us to build the app in a modular way and it would be much easier to maintain. By building on top of an SPA, we would also get the basic app scaffolding that would make things faster and allow us to concentrate on the core business logic.
4. Adopt a Publisher – Subscriber System
While figuring out the components for the app, we figured out that one of the most complicated problems we were trying to solve was that of a publisher / subscriber system. A publisher / subscriber system is when a change made in one part of the system will be informed to the other parts of the system that are interested in knowing that something changed (think of it like push notifications you get from facebook when someone tags you in a photo). Since this was a problem others also face, we wanted to check if there were any existing systems we could leverage.
5. Use a realtime database
We finalized on a realtime database solution that we could leverage. While migrating the code base, we moved the syncing business logic out of the code and started using the database instead. This helped us as we could concentrate more on writing business logic correctly and spend time on other important tasks like user experience etc. that were critical for success. Testing became more easy and reliable as we were not dealing with all the complex synchronization cases that were challenging before.
Challenges encountered while executing
Learning curve of the tech stack
On adopting the hybrid approach the app would be written in HTML / CSS / JS. This didn’t sound like a steep learning curve for Akrity as their team had already worked with building web applications, and they were also writing another web app for building a dashboard.
Risk of architectural constraints
We found a few alternatives that we thought could be interesting and took the decision as a team by analyzing the different pro / cons of the adoption, learning curve, and the impact on other systems. It was very important for us to ensure that we didn’t lock ourselves in with a system and that we were not introducing new constraints because of our decisions at an architectural level.
Benefits AchievedAfter the pivot, we had only one code base that could support both android and iOS at the same time. This meant faster time to market. Adapting this tech stack meant that we needed to work only with business logic and not write any boilerplate code. This further increased development speed by reduced possibility of bugs.
Exciting End Results
The results were quite exciting. We had built a lot of the app from scratch and we did it in a matter of just 5 months. In 5 months we had rewritten the app from scratch and had also pivoted and implemented new functionality with a very small team of 2 developers. This was quite fast compared to having the app built natively. Since we had lesser material to test and we had solved only the right parts of the problem, we were able to push for a faster release.