ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Follow publication

Exposing the separate resources module to iOS target using moko-resources in KMM

Photo by Sophie Elvis on Unsplash

In Android development, modularization of the application is a very common pattern that helps organize the code, increase the readability and make sharing between projects more straightforward. Some say it also decreases the build time, but this is not a part of this article. If you would like to learn more, check out this video from Google I/O’19.

Why make a separate module for resources?

Whenever your modules are features or layers based, the resources like localized texts or icons can be used anywhere in the app UI and reused in many modules. Now when compose is becoming a standard we can create UI-only modules with compose dependencies and app resources. The composables do not need to know about any business class.

In the KMM project, the additional benefit can be seen while importing the module. Having the resources independently, the iOS view class will import only this. Same on the Android side, the common module for a ui-only module will not be needed.

Multiplatform resources

For my KMM projects, I use moko-resources. The library from icerock devs provides access to resources on different platforms with the support of the default system localization.

Let’s implement it step by step:

  • create a separate module for resources:
  • build.gradle needs to include the icerock plugin dev.icerock.mobile.multiplatform-resources and an extension function multiplatformResources that will generate the resources classes. Also, we need to add api keyword to the library dependency (A gist with a full example)
plugins {    
kotlin("multiplatform")
id("com.android.library") id("dev.icerock.mobile.multiplatform-resources")
}
  • After adding the resources to commonMain/resources/MR/base we should be ready to go to use them everywhere. Disclaimer: Pay attention to the resources directory name. Even if we choose the custom name, the directory needs to be named MR
  • At this point, Android works after importing the new resources module, but iOS does not see it in the generated framework. Why?

Exposing the shared resources to the iOS framework

The iOS target depends on KMM import which in my case is shared. I didn’t want to add an extra framework for iOS colleagues, so I needed to expose the resources to the common module. In order to do that we need to modify build.gradle of the shared module.

  • include the icerock plugin dev.icerock.mobile.multiplatform-resources and an extension function multiplatformResources that will generate the resource classes. Also, we need to add api library dependency.

Sounds familiar? This is exactly the same step that we did for the shared resources module before. Check this gist to identify changes in kotlin { } block.

The framework that will be generated for the iOS target needs sharedResources to be exported together with moko-resources dependency. The first one will contain generated classes while the other is allowing the iOS to use a specific library API. Together with the plugin installed and extension function in the common module, this project will build iOS, without any change from iOS devs required.

I believe Kotlin Multiplatform is the framework that will be widely used in the mobile world. The reason is, that the KMM is optional and every team can start testing it and implement only a part of it. The resources are a perfect example of how KMM can reduce the amount of duplicated code on mobile platforms.

Big thanks to Carlos Mota for the review 👍

Published in ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Written by Piotr Prus

Android Developer @Tilt, Enthusiast of kotlin, jetpack compose and clean architecture. Currently Composing and KMMing all the things ❤️

No responses yet

Write a response