Ktor 2.0.3 Help

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

  1. In Android Studio, select File | New | New Project.

  2. Select Kotlin Multiplatform App in the list of project templates, and click Next.

  3. Specify a name for your application, and click Next. In our tutorial, the application name is KmmKtor.

  4. 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

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. Open the shared/build.gradle.kts file and follow the steps below:

  1. Specify Ktor version inside sourceSets:

    sourceSets { val ktorVersion = "2.0.3" }
  2. To use the Ktor client in common code, add the dependency to ktor-client-core to the commonMain source set:

    val commonMain by getting { dependencies { implementation("io.ktor:ktor-client-core:$ktorVersion") } }
  3. Add an engine dependency for the required platform to the corresponding source set:

    • For Android, add the ktor-client-okhttp dependency to the androidMain source set:

      val androidMain by getting { dependencies { implementation("io.ktor:ktor-client-okhttp:$ktorVersion") } }

      For Android, you can also use other engine types.

    • For iOS, add the ktor-client-darwin dependency to iosMain:

      val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) iosArm64Main.dependsOn(this) iosSimulatorArm64Main.dependsOn(this) dependencies { implementation("io.ktor:ktor-client-darwin:$ktorVersion") } }

Add coroutines

In this tutorial, we'll use coroutines in Android code. Open the androidApp/build.gradle.kts and add the following dependencies:

dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1") }

Enable the New Kotlin/Native memory model

To use Ktor client on Kotlin/Native targets (such as iOS), we need to enable the New Kotlin/Native memory model. Open the gradle.properties file and add the following line:

kotlin.native.binary.memoryModel=experimental

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:

class Greeting { private val client = HttpClient() suspend fun getHtml(): String { val response = client.get("https://ktor.io/docs") return response.bodyAsText() } }
  • To create the HTTP client, the HttpClient constructor is called.

  • The suspending getHtml function is used to make a request and receive the body of a response as a string value.

Android code

To call the suspending getHtml function from the Android code, we need to create a coroutine scope. We'll be using MainScope, which can be used as the main coroutine scope for UI components.

Open the androidApp/src/main/java/com/example/kmmktor/android/MainActivity.kt file and update MainActivity code as follows:

class MainActivity : AppCompatActivity() { private val mainScope = MainScope() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val tv: TextView = findViewById(R.id.text_view) tv.text = "Loading..." mainScope.launch { kotlin.runCatching { Greeting().getHtml() }.onSuccess { tv.text = it }.onFailure { tv.text = "Error: ${it.localizedMessage}" } } } }

Inside the created MainScope, the runCatching function is used to call the shared getHtml function and handle possible exceptions.

iOS code

Open the iosApp/iosApp/ContentView.swift file and update ContentView code in the following way:

struct ContentView: View { let greeting = Greeting() @State var greet = "Loading..." func load() { greeting.getHtml { result, error in if let result = result { self.greet = result } else if let error = error { greet = "Error: \(error)" } } } var body: some View { Text(greet).onAppear() { load() } } }

On iOS, the getHtml 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:

<manifest> <uses-permission android:name="android.permission.INTERNET" /> <application> ... </application> </manifest>

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.

Android simulator
iOS simulator
Last modified: 28 June 2022