Breaking the Boundaries of Platform-Specific Development with Kotlin Multiplatform
“In the fast-paced world of mobile app development, developers are constantly searching for new tools and technologies to improve the efficiency of their work. One technology that is gaining traction in the community is Kotlin Multiplatform, a powerful solution for cross-platform development. In this article, we’ll explore what Kotlin Multiplatform is, how it works, and why it’s a game-changer for developers ?”
What is Kotlin Multiplatform ?
Kotlin Multiplatform is a feature introduced in Kotlin 1.2 in 2017. This feature focuses on cross-platform app development and allows you to write the same code on multiple platforms directly. It is based on the ‘Write Once, Run Anywhere’ approach, but it takes the concept to a much higher level, allowing you to write code once and target multiple platforms.
It enables you to include other platforms such as Linux, Windows, and the web (JavaScript), whereas its subset Kotlin Multiplatform Mobile enables developers to write business logic code for iOS and Android from a single codebase.
How does Kotlin Multiplatform work ?
The language, core libraries, and basic tools are all included in Common Kotlin. Code written in common Kotlin runs on all platforms.
You can reuse multiplatform logic in both common and platform-specific code using Kotlin Multiplatform libraries. Common code can rely on a set of libraries that handle common tasks like HTTP, serialisation, and coroutine management.
To interop with platforms, use platform-specific versions of Kotlin. Platform-specific versions of Kotlin (Kotlin/JVM, Kotlin/JS, Kotlin/Native) include extensions to the Kotlin language, and platform-specific libraries and tools.
Through these platforms you can access the platform native code (JVM, JS, and Native) and leverage all native capabilities.
Code Sharing between platforms
- Spend less time creating and maintaining the same code for several platforms with Kotlin Multiplatform and just share it using the tools Kotlin offers.
- Distribute your project’s code across all the platforms you used. Employ it to communicate the universal business logic across all platforms.
- Share some platforms in your project’s code, but not all of them. When you can reuse a large portion of the code across similar platforms, do this.
- Use the Kotlin mechanism of expected and actual declarations if you need to call platform-specific APIs from the shared code.
How Does Multiplatform Differ From Cross Platform?
- A multiplatform system uses both the platform-specific codes for each platform as well as a common code that is used by both platforms while developing software for various platforms.
- A cross-platform application is a system that allows an application to be deployed with the use of the exact same application code.
Sharing common code is the primary goal of the Kotlin multiplatform, which is seen as an improvement over native development.
Getting hands dirty
Before you create your first application that works on both iOS and Android, you’ll need to set up an environment for Kotlin Multiplatform Mobile development.
Make sure you have the latest version of Android version installed.
Note : The following tutorial is going to be Windows specific.
Setting up the Environment:
- To get started, download the Kotlin Multiplatform plugin in Android Studio and restart the IDE.
2. Select the following template for your new KMM project.
3. Specify a name for your first application, and click Next.
4. In the iOS framework distribution list, select the Regular framework option.
5. Keep the default names for the application and shared folders. Click Finish.
Overview of Project structure:
Note: To view full structure, switch the view from Android to Project.
Each Kotlin Multiplatform Mobile project contains three modules.
- shared is a Kotlin module that contains the logic common for both Android and iOS applications — the code you share between platforms. It uses Gradle as the build system that helps you automate your build process. The shared module builds into an Android library and an iOS framework.
- androidApp is a Kotlin module that builds into an Android application. It uses Gradle as the build system. The androidApp module depends on and uses the shared module as a regular Android library.
- iOSApp is an Xcode project that builds into an iOS application. It depends on and uses the shared module as an iOS framework. The shared module can be used as a regular framework or as a CocoaPods dependency, based on what you’ve chosen in the previous step in iOS framework distribution. In this tutorial, it’s a regular framework dependency.
This is an illustration of the structure of a Multiplatform Mobile project that you may create using IntelliJ IDEA’s or Android Studio’s project wizard. Projects in real life sometimes have more intricate architecture.
The MainAactivity.kt file should appear something like this:
package com.myapp.kotlinmultiplatformproject.android
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.myapp.kotlinmultiplatformproject.Greeting
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
GreetingView(Greeting().greet())
}
}
}
}
}
@Composable
fun GreetingView(text: String) {
Text(text = text)
}
@Preview
@Composable
fun DefaultPreview() {
MyApplicationTheme {
GreetingView("Hello, Android!")
}
}
By default Kotlin Multiplatform Mobile uses Jetpack Compose for User Interface.
Create a Simple Login Page
- Add the dependency in the app gradle file as its required for navigation
implementation("androidx.navigation:navigation-compose:2.6.0-alpha06")
- Create Routes.kt file to store the information of routes
sealed class Routes(val route: String) {
object Login : Routes("Login")
}
- Create new package screen
- Create new File inside screen package screen/ScreenMain.kt and paste below code in it.
@Composable
fun ScreenMain(){
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Routes.Login.route) {
composable(Routes.Login.route) {
LoginPage(navController = navController)
}
}
}
- Create new file screen/Login.kt and paste below code in it
@Composable
fun LoginPage(navController: NavHostController) {
Box(modifier = Modifier.fillMaxSize()) {
ClickableText(
text = AnnotatedString("Sign up here"),
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(20.dp),
onClick = { },
style = TextStyle(
fontSize = 14.sp,
fontFamily = FontFamily.Default,
textDecoration = TextDecoration.Underline,
color = Purple700
)
)
}
Column(
modifier = Modifier.padding(20.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
val username = remember { mutableStateOf(TextFieldValue()) }
val password = remember { mutableStateOf(TextFieldValue()) }
Text(text = "Login", style = TextStyle(fontSize = 40.sp, fontFamily = FontFamily.Cursive))
Spacer(modifier = Modifier.height(20.dp))
TextField(
label = { Text(text = "Username") },
value = username.value,
onValueChange = { username.value = it })
Spacer(modifier = Modifier.height(20.dp))
TextField(
label = { Text(text = "Password") },
value = password.value,
visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
onValueChange = { password.value = it })
Spacer(modifier = Modifier.height(20.dp))
Box(modifier = Modifier.padding(40.dp, 0.dp, 40.dp, 0.dp)) {
Button(
onClick = { },
shape = RoundedCornerShape(50.dp),
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
) {
Text(text = "Login")
}
}
Spacer(modifier = Modifier.height(20.dp))
ClickableText(
text = AnnotatedString("Forgot password?"),
onClick = { },
style = TextStyle(
fontSize = 14.sp,
fontFamily = FontFamily.Default
)
)
}
}
- Inside the Mainactivity.kt file add the following code
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
JetpackComposeDemoTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
ScreenMain()
}
}
}
}
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
JetpackComposeDemoTheme {
ScreenMain()
}
}
And we are all done with the login UI which uses Jetpack Compose and essentially works as a multiplatform application.
If you followed this long, the final app should look like this:
Conclusion:
Kotlin Multiplatform is a powerful technology that enables developers to write shared code in Kotlin and run it on multiple platforms, such as Android, iOS, and web. It provides a unified development experience, reduces the amount of code that needs to be written, and offers better performance compared to other cross-platform development solutions. With Kotlin Multiplatform, developers can build robust and scalable apps that work across multiple platforms, while saving time and effort.