Search code examples
xcodekotlinkotlin-multiplatform

MacOS Kmp cannot install ktor dependency


Working with Kotlin KMP and targeting macos and I am having trouble installing a ktor dependency.

Here is my shared module gradle file

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

version = "1.0"

kotlin {
    android()
    jvm()

    val iosTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
        if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
            ::iosArm64
        else
            ::iosX64

    iosTarget("ios") {}
    macosX64("macos")

    cocoapods {
        summary = "Some description for the Shared Module"
        homepage = "Link to the Shared Module homepage"
        // ios.deploymentTarget = AppleSdk.iosDeploymentTarget
        // osx.deploymentTarget = AppleSdk.osxDeploymentTarget
        frameworkName = "shared"
    }
    
    sourceSets {
        val commonMain by getting {
            dependencies {
                // ktor dependencies needs to use old coroutine version
                // https://youtrack.jetbrains.com/issue/KT-46697
                implementation(Kotlinx.coroutineCore)

                // Koin
                implementation(Koin.core)
                implementation(Koin.test)

                // Ktor
                implementation(Ktor.clientCore)
                implementation(Ktor.clientJson)
                implementation(Ktor.clientLogging)
                implementation(Ktor.clientSerialization)

                // serialization
                implementation(Kotlinx.serializationCore)
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
            }
        }
        val androidMain by getting {
            dependencies {
                implementation(Ktor.clientAndroid)
            }
        }
        val androidTest by getting {
            dependencies {
                implementation(kotlin("test-junit"))
                implementation(Test.junit)
            }
        }
        val iosMain by getting {
            dependencies {
                // "io.ktor:ktor-client-ios:1.6.0"
                implementation(Ktor.clientIos)
            }
        }
        val iosTest by getting
        val jvmMain by getting {
            dependencies {
                implementation(Ktor.clientJvm)
            }
        }
        val jvmTest by getting {
            dependencies {
                implementation(kotlin("test-junit"))
                implementation(Test.junit)
            }
        }
        val macosMain by getting {
            dependencies {
                // "io.ktor:ktor-client-cio:1.6.0"
                implementation(Ktor.clientCio)
            }
        }
        val macosTest by getting
    }
}

My solution builds in android studio and I am able to run my solution in xcode for ios. However when I get to the macos target I get this error in xcode:

duplicate symbol '_kclass:io.ktor.network.sockets.SocketTimeoutException' in:
    {redacted}/shared/build/cocoapods/framework/shared.framework/shared(result.o)
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

When I remove the macos ktor dependency it builds just fine. I don't have any extra build gradles that are modified right now, so I know that I am not installing ktor in any extra places currently. I do not get why ios works and macos fails. I The way that I read that xcode error it seems like there is a duplicate ktor method/class? Any help would be greatly appreciated! I am modeling a lot after this repo as well https://github.com/joreilly/PeopleInSpace and the only major difference I can see is that I am still using cocoa pods and the other dev migrated to swift package manager


Solution

  • According to the documentation, Ktor's CIO engine is JVM-only. Try using curl one:

    val macosMain by getting {
                dependencies {
                    implementation("io.ktor:ktor-client-curl:$ktor_version") 
                }
            }