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 }