KMP+CMPのスケルトンプロジェクトをAndroidとiOSで動かしてみた
はじめに
モバイルアプリ開発に携わる中で、「同じ機能をAndroidとiOSで二度実装する」という課題に、頭を悩ませた経験はありませんか?
この課題を解決する希望として、2017年12月にKotlin Multiplatform (KMP)が初めて登場しました。この技術は、ネットワーク通信やビジネスロジックといったアプリの「核」となる部分だけをKotlinで共通化し、プラットフォーム固有のUIはそれぞれの言語(Kotlin/Swift)でネイティブに実装するという革新的なアプローチでした。
当時はまだ実験的な機能でしたが、私は「これで開発効率が劇的に変わる」と大きな期待を抱き、その後のKMPの進化を追い続けてきました。
しかし、KMPでロジックを共有できても、UIをプラットフォームごとに記述する必要があるため、真の「ワンソース・マルチプラットフォーム」の実現には一歩足りませんでした。
そして今、その「最後の一歩」が現実のものとなりました。それが、 Compose Multiplatform (CMP) です。
KMPの技術的成熟を経て、ついに UIレイヤーまでも 共通のKotlinコードで記述し、iOS、Android、Desktop、Webといった多様なプラットフォームで動作させることが可能になったのです。
長年追いかけてきた「フルクロスプラットフォーム」の夢が、KMPとCMPの組み合わせによっていよいよ実現段階に入りました。本記事では、この2つの革新的な技術がそれぞれどのような役割を果たし、私たちの開発スタイルをどのように変えるのかを、詳細に解説していきます。
KMPとCMPの立ち位置
KMPとCMPは、どちらも「Kotlinでマルチプラットフォーム開発を行う」ための技術ですが、それぞれが担当するレイヤー(層)が異なります。
1. KMP:ロジック共有の「土台」 🧱
Kotlin Multiplatform (KMP)は、図のロジック レイヤーを担当する技術です。
- 役割: アプリケーションの「頭脳」となる部分を共通化します。具体的には、データ処理やネットワーク通信、ビジネスロジックなどのコードをKotlinで一度記述し、Android、iOS、Desktop、Webといった異なるプラットフォームで再利用します。
- 強み: UIは各プラットフォームのネイティブ技術(AndroidならCompose for Android/iOSならSwiftUI/UIKitなど)に任せられるため、既存のアプリに少しずつ共通ロジックを導入していくことが容易です。KMPは「ロジック共有」に特化した、柔軟性の高い土台です。
2. CMP:UI共有の「実現者」 🖌️
Compose Multiplatform (CMP)は、図のUI レイヤーを担当します。
- 役割: AndroidでおなじみのJetpack Composeと同じAPIを用いて、ユーザーインターフェース (UI)のコードを共通化します。
- 強み: CMPによって、共通のKotlinコードからAndroid、iOS、Desktop、Web (WebAssembly) のUIを描画できます。
これにより、UIとロジックの両方を一つのコードベースで管理することが可能になり、完全なフルクロスプラットフォーム開発が実現します。開発者はプラットフォーム間のUIの差異を気にすることなく、統一されたUXを素早く提供できます。
要するに、KMPでロジックを共通化し、CMPでUIを共通化する。この二つの技術が組み合わさることで、真の意味で効率的かつ一貫性のあるマルチプラットフォーム開発が可能になるのです。
続いて、実際のプロジェクトを作成手順を確認していきます。
プロジェクトの作成
事前セットアップ
KMPやCMPのプロジェクトを開発するためには、開発環境として広く使われている Android Studio に、JetBrainsが提供する特定のプラグインを導入する必要があります。これにより、マルチプラットフォーム開発に必要なファイル構造の認識、補完、実行設定などがスムーズに行えるようになります。
導入すべきプラグイン
KMPとCMPを導入する時は、それぞれ対応するプラグインが必要です。


特にCMPを使ったプロジェクトのテンプレートやウィザードを利用する場合、これらのプラグインがインストールされていることが前提となります。
次のセクションでは、Android Studioでの新規プロジェクト作成の手順を詳しく解説します。まずはご自身のAndroid Studioを開き、準備を整えましょう!
プロジェクト作成
それでは、いよいよAndroid Studioを起動し、KMPとCMPを活用した新しいマルチプラットフォームプロジェクトを作成していきましょう。
今回は、ロジックだけでなくUIも共有する、最もパワフルな構成である 「Kotlin Multiplatform + Compose Multiplatform」 のプロジェクトテンプレートを使用します。
1. プロジェクトの新規作成開始
Android Studioを起動し、スタート画面から「New Project」を選択します。

2. プロジェクトテンプレートの選択
プロジェクトテンプレートは、Phone and TabletカテゴリのKotlin Multiplatformを選択します

- 「Phone and Tablet」 カテゴリ
- 「Kotlin Multiplatform」
3. プロジェクトの設定
選択後、プロジェクトの基本情報を設定します。

| 項目 | 設定内容の目安 | 補足 |
| Name | MyKmpCmpApp など | プロジェクトの名前です。 |
| Package name | com.example.mykmpcmpapp | 慣例に従って入力してください。 |
| Save location | 任意の場所 例:デスクトップなど | プロジェクトファイルを保存するディレクトリを指定します。 |
4. マルチプラットフォーム設定の確認
どのプラットフォームをターゲットにするかを選択する画面に進みます。

今回は、Android と iOS にチェックを入れます。また、iOSのUI Implementationとして「Share UI」が選択されていることを必ず確認してください。
5. プロジェクトの作成と初期設定
「Finish」ボタンをクリックして、プロジェクトを作成します。
Android Studioがプロジェクト構造を生成し、依存関係の同期(Gradle Sync)を開始します。

同期が完了したら、新しいKMP/CMPプロジェクトの準備は完了です。次のセクションでは、このプロジェクトの構造を解説し、どこに何を書くのかを見ていきましょう!
プロジェクトの構成
🏗️ プロジェクトの構造を理解する:どこに何を書く?
プロジェクトの作成が完了し、Gradle同期が終わると、Android Studioの左側にはファイルツリーが表示されます。KMP/CMPの構造を正確に把握するため、まずは表示方法を変更しましょう。
🚨 重要な最初のステップ:ビューの切り替え
Android Studioを初めて開いた際、ファイルツリーはデフォルトで「Android」ビューになっていることが多いです。しかし、このビューでは、共通モジュール(composeApp)とプラットフォーム固有モジュールが抽象化されてしまい、KMPの実際の構造が見えにくくなります。
プロジェクトの全てのディレクトリとファイルを物理的な構造通りに確認するため、Android Studioの左上にあるドロップダウンからビューを必ず 「Project」 に変更してください。

この「Project」ビューに切り替えることで、KMP/CMPのプロジェクト構造は非常に論理的であることがわかります。
1. 📂 ComposeApp モジュール(共通モジュール)
このディレクトリこそが、KMP/CMPの中核です。プラットフォーム間でコードを共有する場所であり、ほとんどの開発作業はここで行われます。

| ディレクトリ | 役割と内容 |
commonMain | KMP/CMPの主戦場です。ここに記述されたKotlinコードが、全てのプラットフォーム(Android, iOS, Desktop, Web)で共有されます。ビジネスロジック、データモデル、共通のUIコード(Compose Multiplatform)などを格納します。 |
androidMain | Androidプラットフォーム固有の実装(expect/actualメカニズムのactual実装など)や、Android独自の依存関係を記述します。 |
iosMain | iOSプラットフォーム固有の実装(SwiftやObjective-Cへのブリッジングが必要なコードなど)を記述します。 |
2. 📱 プラットフォーム固有のモジュール
composeApp モジュールで作成された共通ロジックと共通UIを利用して、実際にアプリケーションを起動するためのモジュールです。

| ディレクトリ | 役割と内容 |
iosApp | iOSアプリケーションのプロジェクト(Xcodeプロジェクト)です。共通コードをビルドしたフレームワークをリンクし、Swiftのコードからsharedモジュールのエントリポイントを呼び出します。 |
注意点: これらのモジュールは、共通ロジックを利用するための「ランチャー(起動機)」としての役割が主であり、ロジック自体は
sharedモジュールにあります。AndroidはcomposeAppの内容をビルドして起動します。
3. ⚙️ build.gradle.kts ファイル
各モジュールの設定は、build.gradle.ktsファイルで行われます。特に重要なのは以下の2つです。
- プロジェクトルートの
build.gradle.kts: 全体的なビルド設定と、サブプロジェクトへの依存関係を設定します。

composeAppモジュールのbuild.gradle.kts: KMPの肝となる設定ファイルです。commonMainやandroidMainといった各ソースセットに対して、使用するライブラリの依存関係(Dependencies)を設定します。

これでプロジェクトの地図が手に入りました。次に、この構造の中で、どのようにコードを記述し、各プラットフォームで実行するのかを見ていきましょう!
実行
🏃 共通コードの記述と実行:アプリを動かしてみよう
実際にAndroidとiOSの両方で動かしてみましょう。
1. ✏️ 共通 UI コードの確認とデモアプリの理解 (commonMain)
新規プロジェクトを作成した際、composeApp/src/commonMain/【パッケージ名】/kotlin の中に、共通のロジックとUIを持つデモアプリのコードが用意されています。
- ファイル:
App.kt(または同様の名前のファイル) - 内容の確認: このファイルには、Compose Multiplatform で記述された共通 UI が含まれています。「Click me!」ボタン、Kotlinのアイコンを模したキューブ(アニメーション付きの可能性あり)、そしてプラットフォーム名を含むテキストなどが表示されているはずです。
- このUIは、ボタンが押されるとテキストが変わる(例: プラットフォーム名が変わる)など、共通のビジネスロジックが組み込まれています。

2. ▶️ Android アプリの実行
Androidデバイス(またはエミュレーター)で動作を確認します。

- Android Studioの上部にある実行設定ドロップダウンから、
composeAppモジュールが選択されていることを確認します。 - ターゲットデバイスとして、起動済みの Android Emulator または実機を選択します。
- 実行ボタン(▶️) をクリックします。
エミュレーターの画面に、 共通 UI を持つデモアプリが表示されます。ここで「Click me!」ボタンを押して、Androidのバージョンが正しく表示されるかを確認してください。

3. 🍎 iOS アプリの実行
iOSデバイス(またはシミュレーター)での実行には、Mac環境と Xcode のインストールが必要です。

- 実行設定ドロップダウンから、
iosAppモジュールを選択します。 - ターゲットとして、利用可能な iOS Simulator (例: iPhone 15 Pro)を選択します。
- 実行ボタン(▶️) をクリックします。
ビルド後、シミュレーターが起動し、Androidと全く同じ見た目と動作をするデモアプリが表示されます。iOS側でも「Click me!」ボタンを操作し、共通ロジックの動作を確認しましょう。

まとめ:真のコード共有を体感
このデモアプリを通じて、composeApp/src/commonMain の中でたった一度記述した UI コードとロジックが、Android と iOS の両方で全く同じように動作することを確認できました。