2023年元旦にKMMを始めるためのテンプレート作り

# この記事は？

年末から本格的にKMMの勉強を始めた @uehatsu です。せっかく元旦なので新しいKMMプロジェクトを作る手順をまとめてみたいと思います。基本的にAndroid Studioの出す警告に沿って作業しているだけですが、まとまった記事がなかったので勉強がてらまとめてみます。

# AndroidはElectric Eelの夢を見るか？

今回は詳細は省きますが2023/01/01時点のAndroid StudioのStable版であるDolphin 2021.3.1 Patch 1だと、AndroidのUnitテストが正しく動作しないようなので、Electric Eel 2022.1.1 RC3をJetBrains Tool Boxからインストールしました。Electric Eelのインストール後、KMMなどのプラグインをインストールしておきます。

```text
Android Studio Electric Eel | 2022.1.1 RC 3
Build #AI-221.6008.13.2211.9424903, built on December 21, 2022
Runtime version: 11.0.15+0-b2043.56-8887301 aarch64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 12.6.2
GC: G1 Young Generation, G1 Old Generation
Memory: 2048M
Cores: 8
Registry:
    external.system.auto.import.disabled=true
    ide.text.editor.with.preview.show.floating.toolbar=false

Non-Bundled Plugins:
    manjaro.mpb (1.7)
    com.intellij.marketplace (221.6008.18)
    IdeaVIM (1.10.3)
    izhangzhihao.rainbow.brackets (2023.1.0-ij)
    com.jetbrains.kmm (0.5.1(221)-61)
```

# 今回はKotlin Multiplatform Appをターゲットとします

KMMの醍醐味といえばLibrary（？）ですが、今回はAppをターゲットにします。早速プロジェクトを作っていきましょう。

# テンプレートの作成

## なにはともあれ`New Project`

`New Project`から`Kotlin Multiplatform App`を選択し`Next`をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65508/56ba5c4d-cea0-37d4-a0cd-1b194f07ecb9.png)

プロジェクト名やパッケージ名、保存先などを選択します。Minimum SDKはターゲットにするAndroid APIの最小値を選択してください。選択したら`Next`をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65508/1f4dc322-f252-ba04-7e3b-daa016f03242.png)

最後にAndroidやiOSのアプリケーション名、Sharedモジュール名などを選択します。今回はテストも書きたいので`Add sample tests for Shared Module`のチェックを入れておきます。`iOS framework distribution`ですがパッケージマネージャに何を使うかを選択します。ここでは純正の`Regular framework`を選択し`Finish`をクリックしてプロジェクトの雛形ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65508/56d5c3ac-80d7-d0ca-c159-e8a6112c8798.png)

## プロジェクトが完成したのでまずは`git init`など

プロジェクトができたので、この時点でのgit周りの設定を終わらせてしまいます。CUIでもGUIでも構いませんので、git初期化などしてしまいましょう。

```bash:terminal
git init
git add .
git commit -a -m 'First commit'
```

## build.gradle.ktsの更新

`build.gradle.kts`はこの時点で３つあるはずです。

```bash:terminal
% find . -name build.gradle.kts
./shared/build.gradle.kts
./build.gradle.kts
./androidApp/build.gradle.kts
```

まずはトップディレクトリ直下の`build.gradle.kts`を修正します。修正内容はkotlinバージョンを1.7.10から1.7.21にアップデートします。

```diff:/build.gradle.kts
-    kotlin("android").version("1.7.10").apply(false)
-    kotlin("multiplatform").version("1.7.10").apply(false)
+    kotlin("android").version("1.7.21").apply(false)
+    kotlin("multiplatform").version("1.7.21").apply(false)
```

次に`androidApp`配下の`build.gradle.kts`を修正します。`kotlinCompilerExtensionVersion`を更新するついでに、アップデートが出ているパッケージも更新しておきます。パッケージの更新はAndroid Studioがアラートを出してくれているので、それを適応するだけのお手軽更新です。

```diff:/androidApp/build.gradle.kts
-        kotlinCompilerExtensionVersion = "1.3.0"
+        kotlinCompilerExtensionVersion = "1.4.0-alpha02"
（中略）
-    implementation("androidx.compose.ui:ui:1.2.1")
-    implementation("androidx.compose.ui:ui-tooling:1.2.1")
-    implementation("androidx.compose.ui:ui-tooling-preview:1.2.1")
-    implementation("androidx.compose.foundation:foundation:1.2.1")
-    implementation("androidx.compose.material:material:1.2.1")
-    implementation("androidx.activity:activity-compose:1.5.1")
+    implementation("androidx.compose.ui:ui:1.3.2")
+    implementation("androidx.compose.ui:ui-tooling:1.3.2")
+    implementation("androidx.compose.ui:ui-tooling-preview:1.3.2")
+    implementation("androidx.compose.foundation:foundation:1.3.1")
+    implementation("androidx.compose.material:material:1.3.1")
+    implementation("androidx.activity:activity-compose:1.6.1")
```

ファイルの修正が終わったら画面右上の`Sync Now`をクリックしておきます。

`Kotlin migration`を実行するか聞かれます。特に更新されるファイルはありませんが、念の為`Run migration` &gt; `Whole project` &gt; `Analyze`でマイグレーションを実行しておきましょう。

この修正をした状態でも`Duplicate content roots detected`と表示されますが、これは現状無視するしかないようです。Kotlinを1.8.0にアップデートし、色々設定を変更すると出なくなるのですが、そうすると今度はKotlin Compiler ExtensionがKotlinの1.7.21までしか対応していないためAndroid側のアプリ実行時にエラーがでてしまいます。これを緊急避難的に回避する方法はあるのですが、問題が出そうなので今回は1.7.21で止めておきます。

# 動作確認

各種動作を確認していきます。

## androidTest.kt

shared配下のandroidTest.ktを実行します。特に問題はなくテストが通りました。

## commonTest.kt

同じくcommonTest.ktを実行します。特に問題ありませんでした。

## iosTest.kt

同じくiosTest.ktを実行します。環境によっては「iPhone XXが無いよ」的なエラーでテストが通らないことがありますが、その時はXcodeのシミュレータに無いと言われたiPhoneのシミュレータを追加してください。

## Androidエミュレータ実行

Android Appを実行し、正しくエミュレータ上で`Hello, Android xx!`と出ていることを確認します。

## iPhoneシミュレータ実行

iOS Appを実行し、正しくシミュレータ上で`Hello, iOS xx.x!`と出ていることを確認します。

# git commitなど

テンプレートができたので、適宜 git commitしておきます。

# さいごに

ここまで来るのに実はパッケージ依存度のエラーがたくさん出ていました。いろいろなパッケージの依存度が高いのは最近の開発では仕方が無いこととはいえ、もう少しスマートにならないものでしょうか？