Unresolved reference: OkHttp in ktor

2.7k Views Asked by At

I am adding OkHttp in HttpClient. But I am getting error. Unresolved reference: OkHttp. I tried to add library in commonMain of build.gradle.kts, but I think I am missing some steps or doing something wrong. I want to use ktor Http but getting weird issue on my side. Can someone guide me, what am I am missing in my code?

import io.ktor.client.*
import io.ktor.client.engine.*
import io.ktor.client.engine.okhttp.*

fun createHttpClient() {
    val client = HttpClient(OkHttp)
}

build.gradle.kts

plugins {
    kotlin("multiplatform")
    kotlin("native.cocoapods")
    id("com.android.library")
}

version = "1.0"

kotlin {
    android()
    iosX64()
    iosArm64()
    iosSimulatorArm64()

    cocoapods {
        summary = "Some description for the Shared Module"
        homepage = "Link to the Shared Module homepage"
        ios.deploymentTarget = "14.1"
        framework {
            baseName = "kotlinmultiplatformsharedmodule"
        }
    }
    
    sourceSets {
        val commonMain by getting{
            dependencies {
                implementation("io.ktor:ktor-client-okhttp:2.0.0")
                implementation("io.ktor:ktor-client-core:2.0.0")
                implementation("io.insert-koin:koin-core:3.2.0-beta-1")
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test"))
            }
        }
        val androidMain by getting
        val androidTest by getting
        val iosX64Main by getting
        val iosArm64Main by getting
        val iosSimulatorArm64Main by getting
        val iosMain by creating {
            dependsOn(commonMain)
            iosX64Main.dependsOn(this)
            iosArm64Main.dependsOn(this)
            iosSimulatorArm64Main.dependsOn(this)
        }
        val iosX64Test by getting
        val iosArm64Test by getting
        val iosSimulatorArm64Test by getting
        val iosTest by creating {
            dependsOn(commonTest)
            iosX64Test.dependsOn(this)
            iosArm64Test.dependsOn(this)
            iosSimulatorArm64Test.dependsOn(this)
        }
    }
}

android {
    compileSdk = 32
    sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
    defaultConfig {
        minSdk = 21
        targetSdk = 32
    }
}

enter image description here

2

There are 2 best solutions below

7
On BEST ANSWER

Since OkHttp is designed to work on JVM and Android, you can't use it in the common code. You can create a different engine for each platform and inject it into the common code.

Or you can use expect-actual, see: https://ktor.io/docs/http-client-engines.html#mpp-config. You create an expect fun createHttpClient(): HttpClient in the common code, and actual fun createHttpClient(): HttpClient with the implementation for corresponding platform in each of the platform modules.

2
On

Ktor is not working with DexGuard because DexGuard obfuscates and encrypts your app's bytecode, which can interfere with Ktor's ability to work properly. Specifically, DexGuard can change the names of Ktor's classes and methods, which can make it difficult for Ktor to find and load the classes it needs. Additionally, DexGuard can encrypt Ktor's bytecode, which can make it impossible for Ktor to decompile and understand the code. There are a few reasons why DexGuard might interfere with Ktor. First, Ktor uses a lot of reflection, which is a technique that allows code to dynamically load and use classes at runtime. DexGuard can obfuscate or encrypt the names of the classes that Ktor needs to reflect on, which can make it difficult or impossible for Ktor to use reflection. Second, Ktor uses a lot of generics, which are a type of abstraction that allows code to be written in a way that is not tied to specific types. DexGuard can obfuscate or encrypt the names of the generic type parameters, which can make it difficult or impossible for Ktor to use generics. Third, Ktor uses a lot of dynamic proxies, which are objects that are created at runtime and that can be used to intercept and modify method calls. DexGuard can obfuscate or encrypt the names of the dynamic proxies that Ktor uses, which can make it difficult or impossible for Ktor to use dynamic proxies. If you are using DexGuard and you are having problems with Ktor, you can try the following:

  • Disable DexGuard for Ktor's classes. This can be done by adding the following line to your app's proguard-rules.pro file: -keep class io.ktor.** { *; }
  • Use a different proguard alternative, such as R8. R8 is a free and open-source proguard alternative that is also designed to protect your app's bytecode. However, it is generally less aggressive than DexGuard, so it is less likely to interfere with Ktor.
  • Make sure that you are using the latest version of DexGuard. DexGuard is constantly being updated with new features and bug fixes. If you are using an older version of DexGuard, you may be experiencing problems that have been fixed in newer versions.