Contents
1. KMP の基本概念と主なメリット
1‑1. コード共有の実態
Kotlin Multiplatform は commonMain 配下にビジネスロジックやデータ層を置き、プラットフォーム固有の実装は expect / actual で分離します。
- コード共有率:公式ドキュメント(Android Developers)では 「ビジネスロジックは 80 % 以上共通化可能」 と記載されています【[1】】。
- ビルド時間・ランタイム性能:JetBrains のブログ記事 (2023‑12) によると、KMP Gradle Plugin 2.0 系で インクリメンタルコンパイルが最大 30 %、ネイティブ実行時のスタートアップが約 15 % 改善されています【[2】】。
ポイント
- 共通ロジックは1か所だけ書けば Android と iOS の両方で動作。
-expect / actualにより安全にプラットフォーム固有コードを差し込めるので、テストの重複が激減します。
1‑2. 主な活用例
| 項目 | 共通化ライブラリ | 具体的実装イメージ |
|---|---|---|
| ネットワーク層 | Ktor (client‑core) | commonMain に API クライアントを定義し、Android は ktor-client-android、iOS は ktor-client-ios を actual で提供 |
| データベース層 | SQLDelight | 共通スキーマは commonMain に置き、Android は android-driver、iOS は native-driver を使用 |
| コルーチン | kotlinx.coroutines | commonMain で suspend 関数を宣言し、プラットフォームごとのディスパッチャーは actual 実装で切り替える |
2. 開発環境の構築手順
| 項目 | 推奨バージョン | 入手先・設定方法 |
|---|---|---|
| IDE (Android) | Android Studio Flamingo 2023.1.2(2024‑02 リリース) | https://developer.android.com/studio |
| IDE (macOS) | IntelliJ IDEA 2023.2.5(KMP プラグイン内蔵) | https://www.jetbrains.com/idea/download/ |
| Kotlin | 1.9.10 | Gradle kotlin("multiplatform") version "1.9.10" |
| KMP Gradle Plugin | 2.0.20(2024‑03 最新版) | id("org.jetbrains.kotlin.multiplatform") version "2.0.20" |
| Xcode | 15.3(macOS 14.5 以上必須) | Mac App Store |
| CMake / SDK | CMake 3.28, Android SDK Platform‑Tools 34.0.4 | Android Studio → SDK Manager |
2‑1. プラグイン導入手順(Android Studio)
- Android Studio 起動 → Preferences (macOS) / Settings (Windows)
Pluginsタブで Kotlin Multiplatform Mobile を検索し、バージョン 2.0.20 が表示されていることを確認してインストール。- 再起動後、
File > New > Projectから Kotlin Multiplatform Mobile App (Wizard) を選択すると、androidApp,iosApp,sharedの 3 モジュールが自動生成されます。
ポイント:IDE が自動的に
gradle.propertiesにkotlin.native.cacheKind=static等の最適化フラグを付与するため、手作業で設定する必要はありません。
2‑2. iOS ビルド環境
|
1 2 3 4 5 6 7 |
# Xcode コマンドラインツールをインストール(未導入の場合) xcode-select --install # CocoaPods を最新に更新(KMP が Pod 経由で共有モジュールを提供する場合必須) sudo gem install cocoapods pod repo update |
3. 公式 Codelab「Kotlin Multiplatform を使ってみる」実践ガイド
以下は Google の公式 Codelab(2024‑02 更新版)をベースにした、手順ごとのポイントとサンプルコードです。
3‑1. プロジェクト作成
|
1 2 3 4 5 6 |
plugins { kotlin("multiplatform") version "1.9.10" id("com.android.library") id("org.jetbrains.kotlin.native.cocoapods") version "1.9.10" } |
androidAppとiosAppが自動生成され、sharedモジュールが common / android / ios の 3 ソースセットを持ちます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
kotlin { androidTarget() iosX64(); iosArm64() sourceSets { val commonMain by getting { dependencies { implementation("io.ktor:ktor-client-core:2.3.4") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") implementation("com.squareup.sqldelight:runtime:2.0.0") } } val androidMain by getting { dependencies { implementation("io.ktor:ktor-client-android:2.3.4") implementation("com.squareup.sqldelight:android-driver:2.0.0") } } val iosMain by getting { dependencies { implementation("io.ktor:ktor-client-ios:2.3.4") implementation("com.squareup.sqldelight:native-driver:2.0.0") } } } } |
注記:バージョンはすべて 2024‑04 時点の最新 を使用しています。
3‑3. Android アプリ側から共有モジュールを呼び出す
|
1 2 3 4 5 6 7 8 9 10 11 12 |
// androidApp/src/main/java/com/example/app/MainActivity.kt class MainActivity : ComponentActivity() { private val repository = PlatformRepository() // actual 実装は Android 側 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Text(text = "Item count: ${repository.fetchData().size}") } } } |
3‑4. iOS アプリ側の設定(CocoaPods 経由)
iosApp/Podfile に以下を追記し、pod install を実行します。
|
1 2 3 4 5 |
target 'iosApp' do use_frameworks! pod 'shared', :path => '../shared' end |
Xcode で iosApp.xcworkspace を開き、Run → iPhone Simulator でビルドが成功すれば完了です。
ポイント:Codelab の手順をそのまま踏むだけで、IDE が生成する Gradle 設定は正しく機能します。手動で
build.gradle.ktsを書き換える必要は基本的にありません。
4. expect / actual パターンの実装例
4‑1. 共通インタフェース(commonMain)
|
1 2 3 4 5 |
// shared/src/commonMain/kotlin/com/example/data/Repository.kt interface Repository { suspend fun fetchData(): List<Item> } |
4‑2. Android 実装(androidMain)
|
1 2 3 4 5 6 7 8 9 10 11 |
// shared/src/androidMain/kotlin/com/example/data/AndroidRepository.kt actual class PlatformRepository : Repository { private val dao = Room.databaseBuilder( context, AppDatabase::class.java, "app-db" ).build().itemDao() override suspend fun fetchData(): List<Item> = dao.getAll() } |
4‑3. iOS 実装(iosMain)
|
1 2 3 4 5 6 7 8 |
// shared/src/iosMain/kotlin/com/example/data/IosRepository.kt actual class PlatformRepository : Repository { private val driver = SqlDriverFactory.create() // native-driver のラッパー override suspend fun fetchData(): List<Item> = SqlDelightDatabase(driver).itemQueries.selectAll().executeAsList() } |
ポイント:commonMain からは PlatformRepository() を直接生成でき、実行時に Android と iOS のどちらか適切な actual が自動的にバインドされます。
5. 依存関係管理・テスト戦略・実務シナリオ
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
plugins { kotlin("multiplatform") version "1.9.10" id("com.android.library") id("org.jetbrains.kotlin.native.cocoapods") version "1.9.10" } android { compileSdk = 34 namespace = "com.example.shared" defaultConfig { minSdk = 21 } } kotlin { androidTarget() iosX64(); iosArm64() sourceSets { val commonMain by getting { dependencies { implementation("io.ktor:ktor-client-core:2.3.4") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") implementation("com.squareup.sqldelight:runtime:2.0.0") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0") } } val commonTest by getting { dependencies { implementation(kotlin("test")) implementation("org.junit.jupiter:junit-jupiter-api:5.10.0") } } // Android / iOS の実装は省略(上記参照) } } |
5‑2. テスト設定
|
1 2 3 4 5 6 |
tasks.withType<Test> { useJUnitPlatform() } // iosTest は Xcode の XCTest と連携させるだけで、KMP 側のコードは共通テストでカバーできる |
- 共通ユニットテスト:
commonTestでkotlin.test+ JUnit5 を使用。 - Android UI テスト:Espresso + JUnit4(
androidApp/src/androidTest)。 - iOS UI テスト:XCTest(
iosAppTests)を併用し、ビジネスロジックは共通テストで網羅。
5‑3. 実務シナリオ別活用マトリクス
| シナリオ | 共有対象コード | 推奨ライブラリ | 主なメリット |
|---|---|---|---|
| 既存 Android アプリの iOS 移植 | DAO・ネットワーク層 | SQLDelight、Ktor、kotlinx.coroutines | 同一データモデルと API 実装でコード量を 30 % 削減 |
| 新規クロスプラットフォーム製品 | ビジネスロジック全般 | Kotlin 1.9, KMP Gradle Plugin 2.0.20 | 一貫した型安全性と IDE 補完で開発速度が向上 |
| 認証・トークン管理の統一 | OAuth フロー、リフレッシュロジック | Ktor Auth、kotlinx.serialization | プラットフォームごとの UI は別に保ちつつ、セキュリティコードは単一ソースで管理 |
ポイント:Gradle Kotlin DSL と公式マルチプラットフォーム対応ライブラリを組み合わせることで、依存関係の重複が排除されビルドキャッシュ効率が最大化します。
6. まとめ
- KMP の本質は「共通ロジックは 1 カ所、プラットフォーム固有コードは安全に分離」することです。
- 公式数値(80 % 以上の共有率、ビルド時間最大30 %短縮)と JetBrains のベンチマーク(スタートアップ15 %改善)を根拠に、実務での導入効果は十分に期待できます【[1】】【[2】】。
- 開発環境は Android Studio Flamingo 2023.1.2 + Kotlin 1.9.10 + KMP Gradle Plugin 2.0.20、iOS 側は Xcode 15.3 が最低ラインです。
- Codelab 手順をそのまま踏めば、数分で「Android + iOS 両方で動く共有モジュール」が完成します。
- 依存関係管理・テスト戦略は Gradle Kotlin DSL で一元化し、JUnit5 と XCTest の二層テストを組み合わせると品質が保証されます。
次のステップ:本稿のコードをローカルにクローンし、実際にビルド・デバッグしてみてください。疑問点やカスタマイズ要件は公式 Slack(kotlin‑multiplatform)や Stack Overflow の
kotlin-multiplatformタグで質問すると迅速に回答が得られます。
参考文献
- Android Developers – Kotlin Multiplatform (2024‑02 更新)
https://developer.android.com/kotlin/multiplatform?hl=ja - JetBrains Blog – KMP Gradle Plugin 2.0 performance improvements (2023‑12)
https://blog.jetbrains.com/kotlin/2023/12/kmp-gradle-plugin-2-0-performance/ - KotlinLang – Multiplatform project samples (GitHub)
https://github.com/Kotlin/multiplatform-samples - Google Codelab – Kotlin Multiplatform Mobile: Get Started (2024‑02 更新)
https://developer.android.com/codelabs/kmp-get-started?hl=ja