内容
Kotlinの公式サイトにあるKMMのチュートリアル
Get started with Kotlin Multiplatform Mobile を進めていくうち、2023年1月20日現在で動かない箇所があったのでそのメモと対策。ある時期だけ意味をなすと思われる消費期限のありそうな記事。あと使用しているAndroid Studioによっても状況が異なるかもしれない。
対応
1. プロジェクトテンプレートとチュートリアルで関数名が異なる
Create the project from a template のところでKotlin Multiplatform App
を選択してプロジェクトを生成すると Greeting.kt
というファイルが同時にが作られるんだけど、関数名が greet
になっている。
class Greeting { private val platform: Platform = getPlatform() fun greet(): String { return "Hello, ${platform.name}!" } }
だけどUpdate your applicationではgreeting
で話が進んでいくので、まるごとコピペすると別ファイルがエラーになる。
class Greeting { private val platform: Platform = getPlatform() fun greeting(): String { return "Guess what it is! > ${platform.name.reversed()}!" } }
2. KtorをインポートするとiOSでビルドが通らなくなる
Ktor(https://kotlinlang.org/docs/multiplatform-mobile-upgrade-app.html#ktor)のところで必要モジュールを追加すると、iosAppをビルドしようとした時点でエラーが発生するようになる。ログを見るとバージョンの依存関係の問題ということが分かる
> Task :shared:linkDebugFrameworkIosSimulatorArm64 FAILED e: Module "io.ktor:ktor-io (io.ktor:ktor-io-iossimulatorarm64)" has a reference to symbol kotlin.ranges/contains|-4666807430820256279[0]. Neither the module itself nor its dependencies contain such declaration. This could happen if the required dependency is missing in the project. Or if there is a dependency of "io.ktor:ktor-io (io.ktor:ktor-io-iossimulatorarm64)" that has a different version in the project than the version that "io.ktor:ktor-io (io.ktor:ktor-io-iossimulatorarm64): 2.2.1" was initially compiled with. Please check that the project configuration is correct and has consistent versions of all required dependencies. The list of "io.ktor:ktor-io (io.ktor:ktor-io-iossimulatorarm64): 2.2.1" dependencies that may lead to conflicts: 1. "stdlib: 1.7.10" (was initially compiled with "stdlib: 1.6.21") 2. "org.jetbrains.kotlin.native.platform.CoreFoundation: 1.7.10" (was initially compiled with "org.jetbrains.kotlin.native.platform.CoreFoundation: 1.6.21") 3. "org.jetbrains.kotlin.native.platform.darwin: 1.7.10" (was initially compiled with "org.jetbrains.kotlin.native.platform.darwin: 1.6.21") 4. "org.jetbrains.kotlin.native.platform.iconv: 1.7.10" (was initially compiled with "org.jetbrains.kotlin.native.platform.iconv: 1.7.20") 5. "org.jetbrains.kotlin.native.platform.posix: 1.7.10" (was initially compiled with "org.jetbrains.kotlin.native.platform.posix: 1.6.21") 6. "org.jetbrains.kotlinx:atomicfu (org.jetbrains.kotlinx:atomicfu-iossimulatorarm64): 0.18.5" (was initially compiled with "org.jetbrains.kotlinx:atomicfu (org.jetbrains.kotlinx:atomicfu-iossimulatorarm64): 0.17.3")
Kotlin側のバージョンを下げると色々と問題がありそうなのでktorVersionを2.0.3
に下げるとエラーはなくなるのだが、結局すぐ次のiOS APP(https://kotlinlang.org/docs/multiplatform-mobile-upgrade-app.html#ios-app)
というステップでエラーになる。(検索にヒットするかもしれないのでログを貼っておく)
Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: illegal attempt to access non-shared <object>@3fcc308 from other thread at 0 shared 0x10558391b kfun:kotlin.Throwable#<init>(kotlin.String?){} + 95 (/opt/buildAgent/work/67fbc2b507315583/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Throwable.kt:24:37) at 1 shared 0x10557cfef kfun:kotlin.Exception#<init>(kotlin.String?){} + 91 (/opt/buildAgent/work/67fbc2b507315583/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:23:44) at 2 shared 0x10557d223 kfun:kotlin.RuntimeException#<init>(kotlin.String?){} + 91 (/opt/buildAgent/work/67fbc2b507315583/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:34:44) at 3 shared 0x10558f24f kfun:kotlin.native.IncorrectDereferenceException#<init>(kotlin.String){} + 91 (/opt/buildAgent/work/67fbc2b507315583/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/Runtime.kt:34:36) at 4 shared 0x105591d73 ThrowIllegalObjectSharingException + 423 (/opt/buildAgent/work/67fbc2b507315583/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/concurrent/Internal.kt:115:11)
結局色々と調べていくと、Kotlinのバージョンが1.7.20未満だと、メモリ管理の方法が異なる関係でエラーが発生していたようだ。
プロジェクト直下のbuild.gradle.kts
が以下のようになっていた。
plugins { //trick: for the same plugin versions in all sub-modules id("com.android.application").version("7.4.0").apply(false) id("com.android.library").version("7.4.0").apply(false) kotlin("android").version("1.7.10").apply(false) kotlin("multiplatform").version("1.7.10").apply(false) }
これを以下のように編集する
plugins { //trick: for the same plugin versions in all sub-modules id("com.android.application").version("7.3.1").apply(false) id("com.android.library").version("7.3.1").apply(false) kotlin("android").version("1.7.21").apply(false) kotlin("multiplatform").version("1.7.21").apply(false) }
すると今度はAndroid側が動かくなるのでandroidApp/build.gradle.kts
のkotlinCompilerExtensionVersion
を1.3.2
にしてやる必要がある
composeOptions { kotlinCompilerExtensionVersion = "1.3.2" }
雑感
- Android Studio Electric Eelでも動く
- 多分他の動く組み合わせもある
- チュートリアルとサンプルコードは動くうちに叩け。
- 手間がかかった割にこの記事は誰の役にも立たないかもしれない