Introduction
While building apps for iOS and android we often end up writing the same business logic for both the platform. After building couple of mobile apps, this question might have crossed your mind: Why I can’t reuse the same business logic on both the platform? This guide will help you getting started with Kotlin Multiplatform.
Kotlin Multiplatform allows you to write common code that can be shared between Android and iOS. Sharing code between mobile platforms is one of the major Kotlin Multiplatform use cases. It is now possible to build mobile applications with parts of the code, such as business logic, connectivity, and more, shared between Android and iOS.
In this tutorial, we will use Android studio to create our multiplatform project.
Getting Started with Kotlin Multiplatform
Launch your Android studio, create a new project. For this tutorial we are selecting Empty Activity
template. Make sure you select the language as Kotlin
.
Let’s wait for Gradle
to finish its syncing. Once Gradle
is done with its task, let’s create our Shared code module.
Right click on the app
directory and go to New ➔ Module. Select Java or Kotlin Library

Click Next and give the name to your module (I used Shared as my module name). You can now see the newly created Shared module in your Project window.
Let’s do some quick changes to the Shared module folder Structure. Make sure your module folder structure looks similar to this:

Now, let’s update your Shared ➔ build.gradle file to make the module work as multiplatform.
apply plugin: 'kotlin-multiplatform'
kotlin{
targets {
//Xcode sets SDK_NAME environment variable - based on whether the
//target device is a simulator or a real device, the preset should vary
final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \
? presets.iosArm64 : presets.iosX64
//outputKinds - FRAMEWORK would mean that the shared code would be exported as a FRAMEWORK
// EXECUTABLE - produces a standalone executable that can be used to run as an app
fromPreset(iOSTarget, 'ios') {
binaries {
framework('Shared')
}
}
//create a target for Android from presets.jvm
fromPreset(presets.jvm, 'android')
}
//we have 3 different sourceSets for common, android and iOS.
//each sourceSet can have their own set of dependencies and configurations
sourceSets {
commonMain.dependencies {
api 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
androidMain.dependencies {
api 'org.jetbrains.kotlin:kotlin-stdlib'
}
iosMain {
}
}
}
configurations {
compileClasspath
}
// This task attaches native framework built from ios module to Xcode project
// Don't run this task directly,
// Xcode runs this task itself during its build process when we configure it.
// make sure all Gradle infrastructure exists (gradle.wrapper, gradlew)
//and gradlew is in executable mode (chmod +x gradlew)
task packForXCode(type: Sync) {
final File frameworkDir = new File(buildDir, "xcode-frameworks")
final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
final def framework = kotlin.targets.ios.binaries.getFramework("Shared", mode)
inputs.property "mode", mode
dependsOn framework.linkTask
from { framework.outputFile.parentFile }
into frameworkDir
doLast {
new File(frameworkDir, 'gradlew').with {
text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
setExecutable(true)
}
}
}
tasks.build.dependsOn packForXCode
We are doing three things in the above codebase:
- Listing out the target for the shared code. For Android, JVM target. For iOS, target depends on the device type, i.e. simulator or a real device.
- We have defined iOS, Android and common source sets, which will allow different configuration for each source set.
- We have created a task for Xcode to generate framework and add it to our iOS project.
Writing Shared code
For this tutorial we will keep it very simple and create a module that will return current Date in string format. Since JVM Date()
and iOS NSDate()
are different, so we have to update our common code something like this:
In Shared module, create a file commonMain➔kotlin➔Time.kt
. Update the code as:
package com.mobiraft.shared
// We will mark the function as expect when we need to add platform specific code.
expect fun getCurrentDate(): String
// This the common function that will be called by Android and iOS app.
fun getDate(): String {
return "Current Date is ${getCurrentDate()}"
Now, let’s add platform specific code in our androidMain
directory for actual implementation of getCurrentDate()
function for android.
Create a file in androidMain➔kotlin➔AndroidTime.kt and add the below code:
import java.util.*
actual fun getCurrentDate(): String {
return Date().toString()
}
Finally, let’s add the iOS platform specific code in iosMain➔kotlin➔IosTime.kt
import platform.Foundation.NSDate
actual fun getCurrentDate(): String {
return NSDate().toString()
}
On iOS, date is retrieve using NSDate()
. To access native iOS libraries or API in Kotlin/Native we have to import platform.*
package.
With our iOS code also in place, the implementation is complete. Now let’s setup our iOS and Android app to run our Shared module.
Running Android App
On Android running the Shared module is similar to using any other package.
Goto you app’s build.gradle
file and add this line:
implementation project(':Shared')
To use your module function just import it in your file and use it like any other Android module.
package com.mobiraft.kotlinmpp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import getDate //fun from our Shared Module.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<TextView>(R.id.label).text = getDate()
}
}
As you can see above that we are directly just calling our shared function like any other function.
In your Shared module directory structure, instead of adding
kotlin
folder you can add a package name such ascom.xyz.abc
. This will give better readability to your shared module function when you import them.
Running iOS App
Let’s create a new iOS app which will use our Shared module.
Create new iOS project
Launch your Xcode IDE (available on Mac) and select create a new Xcode project.
Select Single View App from the template.

Give your project a name and save it.
Now our iOS project setup is complete, let’s link it with our shared code.
Add the Shared Module
In our Shared Module build.gradle
file we have added a task packForXCode
You can directly run the task from android studio to generate framework, it is usually created at Shared/build/Shared<Debug/Release>Framework/Shared.framework
. This folder contains multiple files along with your framework. To make it easy to find the task, it also pushes out the framework file in build/xcode-frameworks
.
Let’s add this framework to our Xcode project.
- Click on the project under project navigator window.
- Under general tab, scroll down to see Frameworks, Libraries and Embedded content section.

Click on the➕ icon in Frameworks, Libraries and Embedded Content section and from the bottom select Add Other➔Add Files.
Navigate to the Shared module directory and select build/xcode-frameworks/Shared.framework
Once the framework is added, next step is to configure Xcode with the search location of the framework.
Select the Build Setting
tab, search for Framework Search Paths
, add the complete path to your framework from Shared Module directory.
To use your framework, open up the ViewController.swift
file and import the Shared Module at the top of the file.
Update your file with the code below:
import UIKit
import Shared //Our Shared Module
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 25))
label.center = CGPoint(x: 180, y: 280)
label.textAlignment = .center
label.font = label.font.withSize(18)
//Calling our module function
label.text = IosTimeKt.getCurrentDate()
view.addSubview(label)
}
}
Here is the output of both the platform:


Hurray!! Your first Kotlin Multiplatform
project is ready!
This will help you get started with Kotlin Multiplatform. This is just a scratch on the surface. From Sharing a Web service layer, business logic, data models and Database, There’s a lot we can achieve with Kotlin/Native.
Stay tuned for the upcoming tutorials where we will cover how to share Data model and Webservice
layer in Kotlin Multiplatform
.
Checkout another quick article on How To Add Splash Screen in SwiftUI.
If you want to learn how to use SwiftUI
in your existing app, then you can read it here!
or If you want to learn how to use and convert your UIViewControllers
in SwiftUI
, then you can read it here!
One Comment