Incio : a two years experience of KMM Adoption at NBS

NBS.DEV
7 min readFeb 4, 2023

--

Today we are very excited to introduce the Incio. It’s a very pragmatic and opinionated Started Kit for Kotlin Multiplatform for Mobile (KMM) that comes from iterations experience of KMM Adoption. You may find it here and discussion about it at Hijra tech talk.

It’s been two years since our first adoption and being exposed by KMM in 2020. Since then 3 iterations have been made with 4 different projects and 2 versions of KMM, alpha, and beta. Incio enables you to start easily your KMM Projects for Android and iOS Projects whether you want from scratch or develop a new shared module for those platforms. More or less it’s like the outcome of our 2 years of experience to figure out the easiest way to leverage the advantages of KMM at NBS.

As you know, we have many options to develop a high-quality app in the recent mobile space, whether you wanna go with Native or Cross-platform, all the things come with their own tradeoffs that rely on your case. Kotlin Multiplatform for Mobile (KMM) offers a new dimension in utilizing the technology, in this case, Kotlin Native. Rather than rely on 100% in native development that doubles your effort in creating Android and iOS or 100% in cross platforms frameworks which in the end when you have a complex case in dealing with hardware or native SDK/API you still need to write the native codes on both platforms, terms like channel, bridge, and plugin become popular. KMM offers you half and a half of those approaches, On one portion you can take advantage of the shared module which is containing similar codes that can be reused among native platform codes, while the other is still able to maximize the power of being native without having any hassle. This means, you are producing native apps as the outcome.

We have been doing this adoption with good intentions since the beginning, to challenge our assumption and pull over from our ‘engineering comfort zone’, of how we are able to be more productive while maintaining our standard in producing high-quality mobile applications by respecting the existing native framework we have, architecture, codebase, internal tooling, and manpower experience. The last part might be special, as we want everyone in the mobile engineering team to be able to jump to KMM without any constraints whenever they are assigned to, the learning curve has to be short and simple both for Android and iOS engineers. Luckily, Kotlin, and Swift are nearly similar 😃

Was it hard? Yes, at first time, things like always going back and forth between documentation and double check the interoperability were like our daily ritual, including side-by-side between android and iOS engineers to ensure that the things we made were able to work as expected in those platforms and one more thing, InvalidMutabilityException was our closest friend 😅(you know how was like when freeze/unfreeze the mutability-immutability object among the threads were very tricky). So, to ease your jump into it without having a headache like us, Incio is here, it is already weaponized with a pack of basic things that you can use, reuse, and scale based on your development needs and your case. We ensure its maintainability and continuously develop it to make it better.

Basic Functions

What does thing come first in your mind when you are asked to develop an application for Android and iOS? Same functionalities, the same UI (but not experience), and the same how to manipulate the data whether it comes from remote or local sources. The diffs are only in the ways we implement the tech in each platform. But the similarities like manipulating the data sources and orchestrating the business logic are able to be centralized and shared to be reused in each platform while the rest are dealing with UI.UX and application logic implementation. The first two are already set in Incio to avoid you from basic repetitiveness such as:

  1. HTTP Networking
  • HTTP GET
  • HTTP POST
  • HTTP POST MULTIPART
  • HTTP PUT
  • HTTP DELETE
  • Session Authenticator
  • API Error Handler
  • JSON Serializable and Deserializable
  • Chucker Enabled for Android
  • Netfox for iOS

2. Local data source

  • Encryption ready local database for SQLite
  • Encryption ready for key-value persistence (Preference)

3. Build Configs

4. Use Case — Interactor for Business Logic (Domain)

5. Wrap all those things with Native Coroutines

No need to write from scratch to manage those things, the code is still able to be adjusted to your flavor. Just need to clone the repository and you are set to go.

Workflow

What practice we’ve been doing when we work with KMM? We split up the mobile team like the diagram below, we set up two different teams, one for Front End and another for the backend for a shared module.

The front-end (FE) module team will be responsible for the presentation layer, their objectives are to make a design UI.UX from the product design team can be precisely similar as possible and delivered and wired up with relevant application logic. While the backend (BE) module focus on dealing with data sources, business logic, and common utilities. Things when common and can be abstracted are another responsibility. What about the distribution of shared module? You can use mono repository approach (As default) or multi-repository approach (will tell you more in the next post). They work with their own tradeoffs.

High Level Architecture

As we mentioned earlier, this adoption should respect everything we have such as the architecture, standards, and codebase we have. We at NBS are always making similar as possible in the way we do mobile application development among platforms. Our goal is to make it our engineers able to get easier in jumping one platform to others. We develop our own clean architecture style as the core principle and pick the MVVM for native Android and iOS. So when the KMM shows up, the first thing first comes to mind is to only shift the approach not the pattern, with that said, we just shift the tools but the pattern we have been doing many times remains the same. In this way, it is open a new wider space for our mobile engineers to jump into KMM shared module with no hassle. The language and tools barrier is not in our engineering culture.

As our codebase is heavily reliant on RX (Reactive Extension), so the thing on it can be substituted with Native Coroutines — Flow, and the details lay in the shared module are adjusted based on the availability and ability of Kotlin Native basis libraries.

As you can see, the data flow pattern still remains the same all the way from the data — domain in the shared module to the presentation module in each platform. For Android, there’s no issue as we can still translate the object from the inner layer to the LiveData, yes we still love LiveData!. The trickiest part is in iOS, as we use the native coroutines and flow in the inner module, and in the upper layer, we use RxSwift, the way to translate the threading model and get the object from the inner layer, in this case, the output of use case function is to be continuously manipulated all the way up. Thank you to the KMPNativeCoroutines library and its creator that making this process comes easier. This part is the challenging part from the very first beginning especially if you need to transform the objects.

Core Libraries

Incio orchestrates the superb, proven, and well-maintained open-source libraries as the main recipes. Here they are the comparison of the libraries we use on a Native and KMM basis.

To make things wired up, Koin comes into play, as the main actor to define and provide the dependencies you need whether you are in Android or iOS code. If you are not familiar with Koin, we suggest you give it a try. The rest are Ktor, Native Coroutines and Flow, SQL Delight, and Settings, the trickiest part of those libraries is Ktor, if you are Android developers that love OkHTTP-Retrofit so much then look back to the Ktor is a way bit different, in any chances of our experience, you need to understand about its plugin, seems like you are a chef to mix the ingredients manually.

Samples

The available samples have to be already described the concrete implementation of basic functions. Please take some time to explore it, understand the data flow, and how to use it in your project. Don’t hesitate to write an issue if you have any concerns.

Roadmap

There are still a bunch functionalities to be developed based on the case-by-case we have, including the unit test, enable the code generation using KSP, automated multi-repository shared module distribution, proper socket streaming, code documentation and etc. Please do let us know if you have any ideas to add or just send us the PR.

What Next?

The initial release is always not perfect, but we continuously update the Incio and in the next posts we will elaborate more part per part of the samples to get you more understanding of how to leverage its capabilities to help you build your own KMM projects.

Last but not least, Just give it a try, and happy coding!

--

--

NBS.DEV

We are a reliable & experienced mobile engineering company based in Jakarta. Been working with tech unicorns, enterprises, and serving multi sector industries.