Architecting Mobile Apps: a Wolfpack’s Meetup Topic
Native mobile apps can get really big, really fast. How can we be efficient about it?
A Little Bit of Context
We get into the situation of starting new mobile projects quite often. Because of this, we are taking our time trying to perfect our strategy on having the best structure and attitude from the start, while still meeting the needs of our clients.
We have seen that there are lots of trends when considering mobile application architecture, but we have our own take on this.
Let’s start with the ‘why’:
- the initial evaluation of the project is hard and never to accurate at first;
- scalability can become an issue over time;
- code reviews and a consistent structure are indispensable when working in teams with multiple developers.
What Do I Need to Think About?
There are multiple elements that altogether create the architecture of a mobile application: the architectural pattern, used design patterns, strategy for views, and so on. Each element has its own importance factor, with some aspects being platform-specific, therefore by taking into account all elements involved we believe we can construct an overall conclusion for both Android & iOS projects.
Architectural Pattern
This may be the most important decision when starting a new app because it will be the backbone of your project. If refactoring is needed, changing the general architecture will probably be the hardest.
We know there are many choices when it comes to architecture, but we usually focus on the choice between 3 main ones:
- MVC (model-view-controller);
- MVP (model-view-presenter);
- MVVM (model-view-viewmodel).
From our latest experience, we have seen that MVVM might be the best decision for most of the projects out there. It offers the perfect framework for writing decoupled, single-responsibility components, and moving the logic away from the view classes. It’s easier to write and read because all the logic for getting data from repositories or manipulating it is found in the View Model, which is observed by a view.
Data Binding?
The next question that we need to answer is: do we want to approach data binding? Data binding is a design pattern that allows the developer to implement a more declarative and clean way of coding connections between the UI (XML on Android and different options on iOS) and the logic usually handled in the View component (on click behaviours, for example).
The main advantage of data binding is that it offers a new option for writing cleaner code that we didn’t have earlier. The View component has a lot less code that handles logic, so it becomes smaller. The View Model component handles all the logic (as it should be). This offers the possibility of having reusable and easy to find/refactorable code. One great example we have stumbled upon multiple times is implementing a creating and editing item flow or filtering through a long list of items. When using data binding, a lot of the code is reusable because of the decoupling of the logic from the UI in the classes.
On Android, data binding is a native feature, so if possible, there is no reason not to try it. As projects get bigger and you have more and more logic into huge View classes, taking the road of data binding can come like a breath of fresh air. On iOS, your best choice is finding a library that works for you. There are many choices, but most importantly, they are becoming better. We have experimented with a few, and there is one that stuck with us: Bond. This library is based on ReactiveKit. It is well documented and continuously updated.
UI Approach
On Android
On the Android side, things are pretty clear in terms of design — the well known XMLs (we also have the new Navigation Component but it’s still pretty young and unexplored).
On iOS
On the other side, iOS has multiple options:
- Storyboards;
- XIBs;
- UI from code.
As in many other cases, we would recommend to not strictly stick with a single approach, but rather combine them as required for each project. In general, we noticed that Storyboards work well for small and medium projects, providing a clear view of the business flows while also offering a quick approach for screen-to-screen navigation. Furthermore, onboarding for new developers is very easy.
XIBs are more or less the same, but we are limited to designing a single component in a XIB file. Their advantages over storyboards consist of avoiding merge conflicts better (people could work on the same storyboard, but rarely on the same XIB) and also in the reusability of UI components. Last, but not least, creating the UI from Swift code can be tedious at first, but after a while, it can become a habit, and things are going faster. Reusability is at its best, but we lack the visual representation, which can be helpful.
Our take on this topic, creating the UI for iOS apps, would be to try to evaluate the project’s size, complexity, and the degree of reusable components. Then go with Storyboards for linear flows (like a Navigation stack with steps), create XIBs for repetitive components and use code for custom animations, transitions and stuff that’s a bit more complicated.
General Structure
There are many tiny things that come into play in a mobile project through its development lifetime, especially as it grows. Most of these items can be thought of later on, as they are easier to refactor.
One of these items would be the repositories approach. Many projects, especially as they hit a certain size, will need a connection to an API and a local database. When you are having only one of these two, you will probably have only one data source, an interface to handle the queries/API calls, and one repository. When needing both, things get a little bit more complicated. You can re-use the interface and mash it all together, or you can separate the logic. The same goes for the data source and repositories. Having different repositories (one for the local db and one for the remote data) will make everything easier to debug and use in the View Model (as you’ll probably only need one call at a time, either from the API or from the database).
Dependency injection is another important element that can save you a lot of time in the long run. The main usage is injecting these instances of the repository/ies into the View Models. Dependency injection is making testing a lot easier. It also makes it a lot easier to use the instance of the needed class wherever it is needed, without having to re-instantiate. There are many options for this, on both Android and iOS. You can obviously create your own way of doing it, with singletons and just passing the same instance when using it, or you can use libraries. On iOS, there are mixed opinions, but on Android, we found our favourite: Koin. It is very lightweight, easy to configure, and to use.
Tests?
We’re sure you’ve been waiting for this because Unit Tests are a developer’s favourite part … right? Yeah, not really. Unit tests, especially in mobile projects, are often seen as a waste of time, both by developers and especially by clients. However, this can be due to the short/medium term thinking.
We all want to build products as fast as possible, but they should be as good as possible too.
As you might probably think, unit tests are there to detect bugs and issues. They help us make changes to existing components (that have tests written for them, of course) without breaking the existing functionality. This advantage is not that visible at first since everything we develop is new, but in time, when these components need changes, unit tests are there to make sure we don’t mess up. Furthermore, another big advantage that might be easily overlooked is: Unit Tests force us to write code that’s cleaner and easier to maintain.
In order to test our work properly, we need to decouple things and make separate components for each feature or flow. So we end up with a good separation of concerns, with the need to apply principles like Dependency Injection and so on. It is not difficult to put code together and make it work. The challenge is to make it well organised and easy to read/maintain. We encourage at least testing the business logic of mobile apps (in our case, at least test what View Models and Repositories do). See this as an investment in a brighter future for your digital project.
We Had a Blast at Our Meetup
We got the opportunity to share all this information with a group of ~60 people, which meant that our office was pretty full. Although it was at the start of July and many people were going on vacation, we are glad local mobile developers found the time and shared this experience with us.
To make sure we had enough information for everyone, we discussed all of these topics on a real-life example — an events app. Yeah, we know, there are plenty of apps like that out there, but we just wanted to have an easy-to-follow and relatable example. We went through 2 iterations of different complexity. At first, we had only a few screens, 2 or 3 API calls and a tight deadline, but then, the complexity level rose: we needed to handle authentication, filtering, and different screens depending on user actions.
We took this example in order to simulate the working process on a project that is continuously growing and to try to structure a mobile app that can handle scalability.
Conclusions
Building mobile apps may not be as easy as your ex-college friends might think. And it isn’t getting any easier, as both Google and Apple document and recommend new ways of building highly scalable applications. We are closely following these announcements, and we think that this is one of the best ways of staying on the right edge of this problem.
Our own take may provide you with some know-how on the high-level side of things, but the best architecture for you is still the one that you know best and consider the best for your particular case. Also, many things need to be considered, namely deadlines, resources, and team size.
Want to know what Wolves are up to? Check our blog posts with tech trends, how-to articles, and tips for entrepreneurs.
Want to work with us? Because Wolfpack Digital is hiring.
Want us to build your app? Because Wolfpack Digital is the right app development agency for that.