LoginSignup
0
0

More than 5 years have passed since last update.

Kotlin/Nativeマルチプラットフォームプロジェクトで、ktor-client-iosを有効にするとエラー「Undefined symbols for architecture x86_64」が発生する

Posted at

Problem

Kotlin/Nativeマルチプラットフォームプロジェクトで、build.gradleにktor-client-iosを追加すると、iosビルド(linkDebugFrameworkIOS)時にエラーが発生しました。

SharedCode/build.gradle

kotlin {
    targets {
        final
        def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") ? presets.iosArm64 : presets.iosX64

        fromPreset(iOSTarget, 'iOS') {
            compilations.main.outputKinds('FRAMEWORK')
        }

        fromPreset(presets.jvm, 'android')
    }

    sourceSets {
        ...
        iOSMain {
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:0.26.1-rc-conf2"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"

                implementation "io.ktor:ktor-client-ios:$ktor_version"
                implementation "io.ktor:ktor-client-core-ios:$ktor_version"
                implementation "io.ktor:ktor-client-json-ios:$ktor_version"
            }
        }
    }
}

エラーログ

// Undefined symbols for architecture x86_64:
//  "_private_classes_<ktor-utils-ios>_io.ktor.util.DelegatingMutableSet_18", referenced from:

原因を調査したところ、以下のようにMutableMapのfilterをすると、エラーが発生するようでした。

sample.kt
val map = mutableMapOf<Hoge, Fuga>()
val fugas = map.filter { !piyo.contains(it.key) }.map { it.value }

Solution

mapをimmutableに変換してからfilterするようにしたところ、エラーが発生しなくなりました。

ImmutableCollections.kt

class ImmutableList<T> private constructor(private val inner: List<T>) : List<T> by inner {
    companion object {
        fun <T> create(inner: List<T>) = if (inner is ImmutableList<T>) {
                inner
            } else {
                ImmutableList(inner.toList())
            }
    }
}

class ImmutableMap<K, V> private constructor(private val inner: Map<K, V>) : Map<K, V> by inner {
    companion object {
        fun <K, V> create(inner: Map<K, V>) = if (inner is ImmutableMap<K, V>) {
            inner
        } else {
            ImmutableMap(hashMapOf(*inner.toList().toTypedArray()))
        }
    }
}

fun <K, V> Map<K, V>.toImmutableMap(): Map<K, V> = ImmutableMap.create(this)
fun <T> List<T>.toImmutableList(): List<T> = ImmutableList.create(this)
sample.kt
val map = mutableMapOf<Hoge, Fuga>()
val fugas = map.toImmutableMap().filter { !xxx.contains(it.key) }.map { it.value }

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0