borremcqueen
borremcqueen

Reputation: 73

ktor dependency in commonMain of Android Studio multiplatform project unresolved in IDE but code runs

I have an issue with the Android Studio IDE when using the ktor dependency for the commonMain sourceset with kotlin multiplatform. The problem is that the IDE does not recognize this dependency, but the program compiles and runs fine. Furthermore, in the androidMain sourceset the dependency is recognized. I have seen other questions on similar problems, but I have not seen anyone with this problem where the program compiles and runs.

Gradle dependencies

The following is in the build.gradle.kts in the shared folder of the project.

kotlin {
    android()
    ios {
        binaries {
            framework {
                baseName = "shared"
            }
        }
    }
    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-core:1.5.1")
                implementation("io.ktor:ktor-client-cio:1.5.1")
            }
        }
        val androidMain by getting {
            dependencies {
                implementation("com.google.android.material:material:1.2.1")
                implementation("io.ktor:ktor-client-android:1.5.1")
            }
        }
        ...
    }
}

where the dots represent dependencies for other sourcesets, e.g. iosMain which is empty.

In the commonMain code, I have a class KtorTest:

package com.example.myapplication222.shared

import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.*

class KtorTest {
    val client: HttpClient = HttpClient(CIO)

    suspend fun get(): String {
        val res: String = client.get("http://www.7timer.info/bin/api.pl?lon=113.17&lat=23.09&product=astro&output=json")
        return res
    }
}

Main Activity

In the main activity I import and use the KtorTest class to perform a get request.

package com.example.myapplication222.androidApp

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.myapplication222.shared.KtorTest
import kotlinx.coroutines.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        var response = ""

        val c = GlobalScope.launch {
            response = get()
        }

        c.invokeOnCompletion { 
            println("***RESPONSE***");
            println(response) }
    }

    suspend fun get(): String {
        val a = KtorTest()
        return a.get()
    }
}

Result

The program builds and runs and prints out the following.

I/System.out: ***RESPONSE***
    {
        "product" : "astro" ,
        "init" : "2021021700" ,
        "dataseries" : [
        {
            "timepoint" : 3,
            "cloudcover" : 4,
I/System.out:       "seeing" : 6,
            "transparency" : 2,
            "lifted_index" : 15,
            "rh2m" : 5,
            "wind10m" : {
                "direction" : "NE",
                "speed" : 3
            },
            "temp2m" : 20,
            "prec_type" : "none"
        },
    ...
}

where the response is cut short for brevity

Screenshot of Android Studio:

The first screenshot is of KtorTest presented above.

KtorTest in commonMain of shared code in Android Studio kotlin multiplatform project

The second screenshot is of the class KtorTest2, which is exactly the same as KtorTest above except that it is located in the androidMain folder of the shared folder in the multiplatform project.

KtorTest2 in androidMain of shared code in Android Studio kotlin multiplatform project

In these images you can see that the IDE complains about ktor in commonMain, but not in androidMain.

Upvotes: 2

Views: 1155

Answers (2)

borremcqueen
borremcqueen

Reputation: 73

Updating kotlin-gradle-plugin to 1.4.31 in build.gradle.kts of the kotlin multiplatform project fixed this issue

See the following answer for more details: https://stackoverflow.com/a/66913665/14635103

Upvotes: 0

Simon
Simon

Reputation: 1737

You only need to include io.ktor:ktor-client-core in commonMain and actual HTTP engine implementation in desired target. If you want to use CIO engine in android, just include io.ktor:ktor-client-cio in androidMain. Ktor will automatically select available HTTP client available for the platform. You can update the KtorTest class like so (note the absence of engine specification):

class KtorTest {
    val client: HttpClient = HttpClient
}

Upvotes: 1

Related Questions