Kotlin Multiplatform Mobile (KMM)

CI&T Australia
CI&T Australia Tech Blog
6 min readMay 28, 2021

Michael Hallorina, QA, Transpire

Tech Assessment — KMM from a QA perspective

Kotlin Multiplatform Mobile is an SDK that allows the use of the same business logic code in both iOS and Android applications. It was designed to help developers reuse their business logic between mobile platforms, whilst writing platform-specific code only where it’s necessary like to implement a native UI or when working with platform specific APIs.

It uses multi-platform capabilities of Kotlin such as:

  • Multiplatform Grade DSL
  • Kotlin/Native +
  • Kotlin/JVM +
  • Kotlin +

It also uses tools and features designed to improve the experience of building mobile cross-platform applications such as:

  • CocoaPods Integration +
  • Android Studio Plugin

KMM can be integrated seamlessly, whether starting a new project or have a codebase that has grown over the years. Shared code written in Kotlin is compiled to JVM byte code with Kotlin/JVM (as per usual with Android Studio) and to native binaries for iOS with Kotlin/Native. Therefore KMM modules can be used like any other regular mobile library.

Pic credit

There are no restrictions imposed in developing the UI as this is done natively for each platform.

You may decide to share only data layers, using popular libraries such as Ktor or SQLDelight.

Tools Needed

  • Xcode
  • MacOS
  • Android Studio
  • Gradle
  • JDK

The KMM Plugin for Android Studio offers integration with the iOS simulator and iOS device in Android Studio. It gives the ability to run and debug applications and Unit tests on iOS from Android Studio, without having to switch IDEs while working on the shared part of the code.

The project Wizard allows ready-to-run cross-platform mobile applications easily.

Takeaways

  • Alternative to cross platform development
  • Useful if your app shares business logic and also want the UI to be customized natively or use platform specific APIs

How will it help QA?

UI testing is still developed natively as the UI is developed respectively in Android Studio for Android or Xcode for iOS. Makes it easier to test and write same scenarios if both app have been developed using the same or similar elements and naming conventions. iOS code can be viewed in Android Studio without having to open Xcode.

Benefits

  • Good for developers and writing Unit tests
  • More freedom in UI development native to the OS
  • Reduces app development time
  • Provides better access to APIs related to the OS

Limitations

  • Multithreading challenges, based on Coroutines tech with Kotlin which isn’t supported in Swift.
  • Not a Kotlin developer community

Similar Tools / Applications:

KMM is an alternative to developing cross platform applications so it is similar to React-Native or Flutter but also directly using Android Studio and Xcode for the UI.

Cost:

Free to use — a plugin that can be downloaded and installed in Android Studio

Instructions On How To Use:

Environment for KMM Development

Android Studio 4.2 +
Xcode 11.3 +
Kotlin Plugin
Kotlin Multiplatform Mobile Plugin
Latest JDK

Creating a KMM Application

The wizard will create and set up all the dependences in Android Studio.
Create a New Project → Select KMM Application → Tick the checkbox to generate sample tests for project
Select Xcode build phases (packForXcode task) in iOS framework distribution.
Click Finish to set the project up.

Running Application on Android

In run configurations, select androidApp and then click Run.

Running Application on iOS

In Xcode Configure the Signing Capabilities and Select a team.
In Android Studio, choose iosApp in run configurations and then click Run.

Running Unit Tests

iOS : Open the file iosTest.kt in shared/src/iosTest/Kotlin/com.example.appname.shared
Click Run icon in the gutter next to the test.

Android: Open the file androidTest.kt in shared/src/androidTest/kotlin/com.example.appname.shared
Click Run icon in the gutter next to the test

Adding KMM to An Existing Android Project

1. Decide Which Code To Make Cross-Platform
Since the business logic will be the same for both iOS and Android, this will be the code that will be made cross-platform. The business logic is stored in the data folder in an Android application: com.application.androidapp.data

2. Create A Shared Module For Cross-Platform Code
A shared folder needs to be created which will later connect the existing Android app and future iOS app. KMM provides a special wizard for creating this module:

File → New → New Module
Select KMM Shared Module and name it ‘shared’
Tick the Generate packForXcode Gradle task checkbox
Click Finish

3. Add A Dependency On The Shared Module To Android Application
The shared module needs to connect to the Android app by moving the business logic there and also ensuring some dependencies and configurations are updated.
In the build.gradle.kts in the shared module, compileSdkVersion and minSdkVersion needs to be the same as build.gradle in the Android app module.
In the build.gradle of Android app module, add the following dependencies:

implementation project(‘:shared’)

Sync the gradle.

4. Make The Business Logic Cross-Platform
The business logic in the Android module needs to be moved to the Shared module. Drag the ‘data’ folder from:

app/src/main/com.application.androidapp directory

to the shared directory: shared/src/commonMain.

Select to move the package and then approve the refactoring.

5. Run The Cross-Platform App On Android To Ensure It Works

Making Cross Platform App Work On iOS

1. Create An iOS Project In Xcode

File → New → Project
Select iOS App and Click Next
Put the same name as the App but with .ios at the end
Select the location which is in the directory that stores the cross platform application.

2. Compile The Shared Module Into A Framework For The iOS Project

In Android Studio type the following command in the Terminal:

./gradlew packForXcode

The generated framework will be stored in shared/build/xcode-frameworks directory

3. Connect The Framework To The iOS Project

In Xcode open the project settings
Under the General tab click the + under ‘Frameworks, Libraries, and Embedded Content’
Click Add Other then Add Files
Select the generated framework: shared/build/xcode-frameworks/shared.framework
Under the Build Settings tab under Search Paths, specify the Framework Search Paths:

$(SRCROOT)/../shared/build/xcode-frameworks

4. Automate iOS Project Updates

Configure automatic updates of the iOS project by avoiding recompiling framework after every change. Under Build Phases tab click + and add New Run Script Phase
Add the following script:

cd “$SRCROOT/..”

./gradlew :shared:packForXcode -PXCODE_CONFIGURATION=${CONFIGURATION}

Drag and move the Run Script phase before the Compile Sources phase

5. Connect The Shared Module To The iOS Project

In Xcode open the ContentView.swift file and import the shared module:

import shared

6. Connect iOS application to Android Studio to run on a simulated or connected device
In Advanced Studio, at the bottom of the gradle.properties file add the following line:

xcodeproj=iosApp/applicationName.xcodeproj

(replace application name with the name you have given)

Adding UI Tests for Android

In the Android module of a KMM app, UI tests can be implemented.

Test are created in the androidApp/src/androidTest/java folder

In build.gradle file of the Android module, the following dependencies need to be added:

In the defaultConfig section, the testInstrumentationRunner needs to be added:

testInstrumentationRunner “androidx.test.runner.AndroidJunitRunner”

Sync the gradle.

After creating a test, run the test to confirm the tests are working.

Adding UI Tests for iOS

UI tests can be configured when creating a KMM app, or when adding the iOS module to a KMM app if the “Add UI tests” box is ticked in the wizard.

If it wasn’t added, it can easily be configured as follows:

Open the iOS app in XCode
File → New → Target
Select iOS UI Testing Bundle
Click Finish

This will create a test class with some sample tests.

Recording a Test

At the top of the class add the following line:

var app: XCUIApplication!

Remove the tearDown function.

Inside the setUp function, replace contents with:

try super.setUpWithError()
continueAfterFailure — false
app = XCUIApplication()
app.launch()

Create a test function inside the class and inside the function press the Record button which will launch the app.
Interact with the app and when finished click the record button again to stop recording the test.
The function should have saved the interactions.
Edit and add assertions as necessary.

--

--

CI&T Australia
CI&T Australia Tech Blog

CI&T partner with the world’s most valuable brands to build digital solutions that transform businesses