Creating a cross-platform mobile application
The Ktor HTTP client can be used in multiplatform projects. In this tutorial, we'll create a simple Kotlin Multiplatform Mobile application, which sends a request and receives a response body as plain HTML text.
Prerequisites
First, you need to set up an environment for cross-platform mobile development by installing the necessary tools on a suitable operating system. Learn how to do this from the Set up an environment section.
Create a new project
To start a new Kotlin Multiplatform project, there are two approaches available:
You can create a project from a template within Android Studio.
Alternatively, you can use the Kotlin Multiplatform Wizard to generate a new project. The wizard provides options for customizing your project setup, allowing you to exclude Android support or include a Ktor Server, for instance.
For the sake of this tutorial, we will demonstrate the process of creating a project from a template:
In Android Studio, select File | New | New Project.
Select Kotlin Multiplatform App in the list of project templates, and click Next.
Specify a name for your application, and click Next. In our tutorial, the application name is
KmmKtor
.On the next page, leave the default settings and click Finish to create a new project. Now, wait while your project is set up. It may take some time to download and set up the required components when you do this for the first time.
Configure build scripts
Update Kotlin Gradle plugins
Open the gradle/libs.versions.toml
file and update the Kotlin version to the latest:
Add Ktor dependencies
To use the Ktor HTTP client in your project, you need to add at least two dependencies: a client dependency and an engine dependency.
In the gradle/libs.versions.toml
file add the Ktor version:
Then, define the Ktor client and engine libraries:
To add the dependencies, open the shared/build.gradle.kts
file and follow the steps below:
To use the Ktor client in common code, add the dependency
ktor-client-core
to thecommonMain
source set:sourceSets { commonMain.dependencies { implementation(libs.ktor.client.core) } }Add an engine dependency for each required platform to the corresponding source set:
For Android, add the
ktor-client-okhttp
dependency to theandroidMain
source set:androidMain.dependencies { implementation(libs.ktor.client.okhttp) }For Android, you can also use other engine types.
For iOS, add the
ktor-client-darwin
dependency toiosMain
:iosMain.dependencies { implementation(libs.ktor.client.darwin) }
Add coroutines
To use coroutines in Android code, you need to add kotlinx.coroutines
to your project:
Open the
gradle/libs.versions.toml
file and specify the coroutines version and libraries:[versions] coroutines = "2.0.0" [libraries] kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" }Open the
build.gradle.kts
file and add thekotlinx-coroutines-core
dependency to thecommonMain
source set:sourceSets { commonMain.dependencies { implementation(libs.ktor.client.core) implementation(libs.kotlinx.coroutines.core) } }Then, open the
androidApp/build.gradle.kts
and add thekotlinx-coroutines-android
dependency:
Click Sync Now in the top right corner of the gradle.properties
file to install the added dependencies.
Update your application
Shared code
To update code shared between Android and iOS, open the shared/src/commonMain/kotlin/com/example/kmmktor/Greeting.kt
file and add the following code to the Greeting
class:
Android code
To call the suspending greeting
function from the Android code, we'll be using rememberCoroutineScope.
Open the androidApp/src/main/java/com/example/kmmktor/android/MainActivity.kt
file and update MainActivity
code as follows:
Inside the created scope, we can call the shared greeting
function and handle possible exceptions.
iOS code
Open the
iosApp/iosApp/iOSApp.swift
file and update the entry point for the application:import SwiftUI @main struct iOSApp: App { var body: some Scene { WindowGroup { ContentView(viewModel: ContentView.ViewModel()) } } }Open the
iosApp/iosApp/ContentView.swift
file and updateContentView
code in the following way:import SwiftUI import shared struct ContentView: View { @ObservedObject private(set) var viewModel: ViewModel var body: some View { Text(viewModel.text) } } extension ContentView { class ViewModel: ObservableObject { @Published var text = "Loading..." init() { Greeting().greeting { greeting, error in DispatchQueue.main.async { if let greeting = greeting { self.text = greeting } else { self.text = error?.localizedDescription ?? "error" } } } } } }On iOS, the
greeting
suspending function is available as a function with a callback.
Enable internet access on Android
The final thing we need to do is to enable internet access for the Android application. Open the androidApp/src/main/AndroidManifest.xml
file and enable the required permission using the uses-permission
element:
Run your application
To run the created multiplatform application on the Android or iOS simulator, select androidApp or iosApp and click Run. The simulator should display the received HTML document as plain text.