DEV Community

Cover image for Coil and Ktor in Kotlin Multiplatform Compose project
Nayden Gochev
Nayden Gochev

Posted on

Coil and Ktor in Kotlin Multiplatform Compose project

Many people are trying but having a hard time adding Coil in a Multiplatform compose project that works on both JVM/Android/iOS and WASM.

Now we have to use Ktor since okHttp is android only for now.
We will be using:

After spending half a day making it work I decide to share it for others.

I will be using the latest versions that support wasm as of 14.06.2024, for later readers and experimenting you might want to upgrade the versions.

1) Libraries and versions

In short first you need to add ktor. In your libs.versions.toml add

[versions]

ktor = "3.0.0-wasm2"

Enter fullscreen mode Exit fullscreen mode
[libraries]
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }
ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
ktor-client-java = { group = "io.ktor", name = "ktor-client-java", version.ref = "ktor" }
ktor-serialization-kotlinx-json = { group = "io.ktor", name = "ktor-serialization-kotlinx-json", version.ref = "ktor" }
ktor-client-serialization = { group = "io.ktor", name = "ktor-client-serialization", version.ref = "ktor" }
ktor-client-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref = "ktor" }
ktor-client-json = { group = "io.ktor", name = "ktor-client-json", version.ref = "ktor" }
ktor-client-logging = { group = "io.ktor", name = "ktor-client-logging", version.ref = "ktor" }
Enter fullscreen mode Exit fullscreen mode

now you can also create a bundle since this makes your build.gradle.kts far smaller so just add the bundle as well

[bundles]
ktor-common = ["ktor-client-core", "ktor-client-json", "ktor-client-logging", "ktor-client-serialization", "ktor-client-content-negotiation", "ktor-serialization-kotlinx-json"]
Enter fullscreen mode Exit fullscreen mode

Now you can stop here if you only need to use ktor in your multiplatform compose projects, in such case scroll down to point 2 updating your build script, however if you want to use coil you need 4 extra dependancies

Add this version

[versions]
coilComposeCore = "3.0.0-alpha06"
Enter fullscreen mode Exit fullscreen mode

and this 4 libraries

[libraries]

coil = { module = "io.coil-kt.coil3:coil", version.ref = "coilComposeCore" }
coil-compose-core = { module = "io.coil-kt.coil3:coil-compose-core", version.ref = "coilComposeCore" }
coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coilComposeCore" }
coil-network-ktor = { module = "io.coil-kt.coil3:coil-network-ktor", version.ref = "coilComposeCore" }
Enter fullscreen mode Exit fullscreen mode

Now you are good to go to your build.gradle.kts file

updating your build script

Open your build.gradle.kts

add maven("https://maven.pkg.jetbrains.space/kotlin/p/wasm/experimental") to your repositories so you can download the ktor wasm version

allprojects {
    repositories {
        google()
        mavenCentral()
maven("https://maven.pkg.jetbrains.space/kotlin/p/wasm/experimental")
    }
}
Enter fullscreen mode Exit fullscreen mode

then in commonMain.dependancies add

commonMain.dependencies {
....
            implementation(libs.bundles.ktor.common)
            implementation(libs.coil.compose.core)
            implementation(libs.coil.compose)
            implementation(libs.coil)
            implementation(libs.coil.network.ktor)
Enter fullscreen mode Exit fullscreen mode

in Android dependancies add

        androidMain.dependencies {
....
  implementation(libs.ktor.client.okhttp)
        }
Enter fullscreen mode Exit fullscreen mode

in iOS/Apple dependancies add

      iosMain.dependencies {
            implementation(libs.ktor.client.darwin)
        }
Enter fullscreen mode Exit fullscreen mode

in JVM dependancies add

 jvmMain.dependencies {
            ....
            implementation(libs.ktor.client.java)
        }
Enter fullscreen mode Exit fullscreen mode

Thats it more or less for dependancies.

NOTE you might need also kotlinx.serialization, if you have it ignroe this and scroll to 3 how to verify coil is working.
so in libs add

[versions]

kotlinx-serialization = "1.6.3"

[libraries]

kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
Enter fullscreen mode Exit fullscreen mode

then in your gradle kts file

plugins {
....
    alias(libs.plugins.kotlinx.serialization)
}
Enter fullscreen mode Exit fullscreen mode

and only in

commonMain.dependencies {
....
implementation(libs.kotlinx.serialization.json)
Enter fullscreen mode Exit fullscreen mode

Thats it you are good to use Ktor in your multiplatform compose project or Ktor + Coil .

How to verify coil is working ?

Example how to use coil can be found over the internet but in short in your App.kt in commonMain add this function

fun getAsyncImageLoader(context: PlatformContext)=
    ImageLoader.Builder(context).crossfade(true).logger(DebugLogger()).build()
Enter fullscreen mode Exit fullscreen mode

Then in your App function just add this

@Composable
internal fun App() = AppTheme() {

    setSingletonImageLoaderFactory { context ->
        getAsyncImageLoader(context)
    }
.... rest code
Enter fullscreen mode Exit fullscreen mode

and then you can use Coil.. for example like this :

                            AsyncImage(
                                model = "https://1.bp.blogspot.com/-m4g5Q9WZuLw/YO7FxYJsnsI/AAAAAAAA6fs/nyDiNA_6EHMrPw3qRLJ7FcR1-MoC4rkZwCLcBGAsYHQ/s0/javabeer.jpg",
                                placeholder = painterResource(Res.drawable.ic_cyclone),
                                contentDescription = null,
                                contentScale = ContentScale.Crop,
                                modifier = Modifier.clip(CircleShape)
                            )

Enter fullscreen mode Exit fullscreen mode

I hope this is helpful for someone ! And go enjoy coding with multiplatform compose, I hope I saved you the 4 hours I lost.

P.S. I use kotlin 2.0 and compose 1.6.11 and serialization 1.6.3

Top comments (3)

Collapse
 
lamplis profile image
Laurent A

Thank you so much
I couldn't make it work for 2 days

Collapse
 
lamplis profile image
Laurent A • Edited

This little tutorial is great.
In the end I still can't download from internet with my android emulator :

🚨 Failed - https://1.bp.blogspot.com/-m4g5Q9WZuLw/YO7FxYJsnsI/AAAAAAAA6fs/nyDiNA_6EHMrPw3qRLJ7FcR1-MoC4rkZwCLcBGAsYHQ/s0/javabeer.jpg - java.lang.NoClassDefFoundError: Failed resolution of: Lio/ktor/utils/io/jvm/nio/WritingKt;
Enter fullscreen mode Exit fullscreen mode

Solved by using
io.coil-kt.coil3:coil-network-ktor3
instead of
io.coil-kt.coil3:coil-network-ktor

with coilComposeCore = "3.0.0-rc01"

Collapse
 
naymello profile image
Nay Mello

thank you very much, you've just saved my day