Contents
はじめに ― Kotlin Multiplatform の概要と本稿の対象読者
Kotlin Multiplatform(以下 KMP)は、共通ロジックを一つのコードベースで記述し、Android と iOS にそれぞれネイティブにビルドできる 仕組みです。本記事では、2024 年時点で 公式が推奨している最新安定版ツールチェーン(Android Studio Giraffe、Kotlin 1.9 系、Gradle 8.x)を前提に、以下の内容を網羅的に解説します。
- Android Studio のインストールと設定
- JDK 17 以上の環境構築手順
- KMP プロジェクトの雛形作成と
sourceSetsの基本構成 - iOS 側への組み込み(CocoaPods と Swift Package Manager (SPM) の選択基準・設定手順)
- 共通コードのテスト、CI/CD(GitHub Actions)までのフロー
**※ 本稿で取り上げるバージョンは執筆時点(2024‑05)の「最新安定版」です。将来的に新しいリリースが出た場合は、公式ドキュメントを参照して適宜置き換えてください。
1. 前提条件とツールのインストール
| ツール | 推奨バージョン (2024‑05) | 主な入手先 |
|---|---|---|
| Android Studio | Giraffe(Android Studio 2023.3.x) | https://developer.android.com/studio |
| JDK | 17 以上(OpenJDK 17 が最も汎用的) | Homebrew / apt / SDKMAN! |
| Kotlin | 1.9 系(例: 1.9.22) |
Gradle が自動取得 |
| Gradle | 8.x(例: 8.4) |
Gradle Wrapper 推奨 |
1‑1. JDK 17 のインストールと Android Studio での設定
|
1 2 3 4 5 6 |
# macOS (Homebrew) brew install openjdk@17 # Ubuntu/Debian 系 sudo apt-get update && sudo apt-get install -y openjdk-17-jdk |
インストール後、Android Studio を起動し File > Settings > Build, Execution, Deployment > Build Tools > Gradle で「Gradle JDK」を JDK 17 に設定します。これだけで Gradle 8.x が要求する最低バージョンは満たされます。
1‑2. Kotlin Multiplatform プラグインの有効化
- Preferences > Plugins を開く
- 「Kotlin Multiplatform」を検索し Install → 再起動
- 再起動後、
File > New > Projectに「Kotlin Multiplatform」テンプレートが表示されることを確認
2. プロジェクトの作成と基本構成
| 手順 | 内容 |
|---|---|
| 1 | File → New → Project を選択 |
| 2 | 「Kotlin Multiplatform → Kotlin Multiplatform Mobile (Shared Module)」を選ぶ |
| 3 | プロジェクト名 MyKmpApp、パッケージ com.example.mykmpapp を入力し Finish |
作成されたプロジェクトは次のディレクトリ構造になります(抜粋):
|
1 2 3 4 5 6 |
shared/ └─ src/ ├─ commonMain/ ├─ androidMain/ └─ iosMain/ |
2‑2. Gradle Kotlin DSL (build.gradle.kts) のポイント
|
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 36 37 38 39 40 |
plugins { kotlin("multiplatform") version "1.9.22" // 最新安定版を使用 id("com.android.library") } kotlin { androidTarget() iosX64() iosArm64() iosSimulatorArm64() sourceSets { val commonMain by getting { dependencies { implementation("io.ktor:ktor-client-core:2.3.5") implementation("io.ktor:ktor-client-content-negotiation:2.3.5") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0") } } val androidMain by getting { dependencies { implementation("io.ktor:ktor-client-okhttp:2.3.5") } } val iosMain by getting { dependencies { implementation("io.ktor:ktor-client-darwin:2.3.5") } } } } android { compileSdk = 34 namespace = "com.example.mykmpapp" defaultConfig { minSdk = 21 } } |
主なポイント
kotlin("multiplatform") version "...は Gradle が自動で最新安定版を取得するので、バージョン番号は「現在の安定版」を記載すれば問題ありません。androidTarget()と iOS 用の 3 種類(シミュレータ・実機)を同時に宣言し、ビルド対象を網羅しています。- 共通依存 (
commonMain) に Ktor + kotlinx‑serialization の組み合わせを採用。モジュール間でコードが共有でき、テストも一元化できます。
3. iOS 側への統合 ― CocoaPods と Swift Package Manager の比較と設定手順
3‑1. 選択基準(いつどちらを選ぶべきか)
| 観点 | CocoaPods | Swift Package Manager (SPM) |
|---|---|---|
| 成熟度 | 10 年以上の実績、Objective‑C/Swift 混在プロジェクトでも安定 | 新しいが Xcode に標準統合、設定がシンプル |
| ビルド速度 | pod install 後はフレームワークを再利用できるため高速 |
依存解決とビルドは Xcode が自動管理 |
| CI/CD への組み込み | bundle exec pod install が必要だが、スクリプト化しやすい |
swift package resolve が標準でサポートされ、macOS ランナーだけで完結 |
| バイナリ配布 | .framework 形式のバイナリを簡単に組み込める |
.xcframework 推奨。Xcode 14+ で直接扱える |
| 推奨シーン | 既存プロジェクトが CocoaPods を使用中、Objective‑C が混在 | 新規プロジェクトか、Xcode の UI だけで完結したい場合 |
結論:既に CocoaPods を採用しているチームはそのまま継続しやすく、ゼロから構築する場合は SPM が手軽です。
3‑2. CocoaPods の具体的な組み込み手順
- Podspec の作成(
shared/podspec.yaml)
gradle.propertiesにkotlin.native.cocoapods.enabled=trueを追記し、./gradlew podspecで自動生成できますが、ここでは手書き例を示します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Pod::Spec.new do |s| s.name = 'Shared' s.version = '1.0.0' s.summary = 'KMP shared module for Android & iOS' s.homepage = 'https://github.com/yourorg/MyKmpApp' s.license = { :type => 'Apache-2.0', :file => 'LICENSE' } s.author = { 'Your Name' => 'you@example.com' } s.source = { :git => 'https://github.com/yourorg/MyKmpApp.git', :tag => s.version.to_s } # Kotlin Multiplatform が生成するフレームワークへのパス s.vendored_frameworks = 'build/cocoapods/framework/Shared.framework' s.platform = :ios, '15.0' s.dependency 'KotlinMultiplatform', '~> 1.9.22' # Kotlin のバージョンに合わせる end |
- Podfile に記述(iOS アプリ側)
|
1 2 3 4 5 6 7 8 |
# ios/Podfile platform :ios, '15.0' target 'MyApp' do use_frameworks! pod 'Shared', :path => '../shared' # パスは KMP モジュールの相対位置 end |
- インストール
|
1 2 3 4 5 |
cd ios bundle install # Bundler が無い場合は gem install bundler bundle exec pod install open MyApp.xcworkspace |
- Xcode 側でフレームワークを使用
Sharedが自動的にリンクされるので、Swift/Obj‑C のコードからimport Sharedすれば共通ロジックが利用可能です。
3‑3. Swift Package Manager (SPM) の具体的な組み込み手順
Package.swiftにバイナリターゲットを追加(KMP が生成した.xcframeworkを使用)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// shared/Package.swift import PackageDescription let package = Package( name: "Shared", platforms: [.iOS(.v15)], products: [ .library(name: "Shared", targets: ["Shared"]) ], targets: [ // Kotlin がビルドした xcframework をそのまま取り込む .binaryTarget( name: "Shared", path: "./build/bin/Shared.xcframework" ) ] ) |
-
Xcode からパッケージを追加
-
Xcode →
File > Add Packages... - Git リポジトリ URL(例:
https://github.com/yourorg/MyKmpApp.git) を入力 -
「Dependency Rule」は
Exact Version、バージョンは1.0.0などタグで管理 -
プロジェクトにリンク
追加したパッケージが左ペインに表示されたら、対象の iOS アプリターゲット → Frameworks, Libraries, and Embedded Content に Shared をドラッグ&ドロップ。これだけで Swift コードから import Shared が可能になります。
- CI への組み込み
GitHub Actions の macOS ランナーは SPM が標準装備されているため、以下のステップだけで依存解決が完了します。
|
1 2 3 |
- name: Resolve Swift Packages run: xcodebuild -resolvePackageDependencies -project MyApp.xcodeproj |
4. テスト・CI/CD のベストプラクティス
4‑1. 共通コードのユニットテスト(commonTest)
KMP では JUnit5 と kotlin.test を組み合わせて、Android と iOS の両方で同一テストを走らせられます。
|
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 |
// shared/src/commonTest/kotlin/com/example/mykmpapp/NetworkClientTest.kt import io.ktor.client.* import io.ktor.client.engine.mock.* import io.ktor.client.request.* import kotlinx.coroutines.runBlocking import kotlin.test.Test import kotlin.test.assertEquals class NetworkClientTest { private val client = HttpClient(MockEngine) { engine { addHandler { request -> respond( content = """{"message":"ok"}""", headers = headersOf("Content-Type", "application/json") ) } } } @Test fun `GET request returns expected JSON`() = runBlocking { val result: String = client.get("https://example.com/hello") assertEquals("""{"message":"ok"}""", result) } } |
- 実行方法
bash
./gradlew :shared:testDebugUnitTest # Android 用テスト
./gradlew :shared:iosX64Test # iOS シミュレータ用テスト(macOS ランナーで実行)
4‑2. GitHub Actions によるマルチプラットフォーム CI
|
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 36 37 38 39 40 41 42 43 44 |
name: KMP CI on: push: branches: [ main ] pull_request: branches: [ main ] jobs: android: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up JDK 17 uses: actions/setup-java@v4 with: distribution: temurin java-version: '17' - name: Install Android SDK uses: android-actions/setup-android@v2 - name: Build & Test (Android) run: ./gradlew :shared:testDebugUnitTest assembleDebug ios: runs-on: macos-latest steps: - uses: actions/checkout@v4 - name: Set up JDK 17 uses: actions/setup-java@v4 with: distribution: temurin java-version: '17' - name: Resolve Swift Packages (SPM) run: xcodebuild -resolvePackageDependencies -project ios/MyApp.xcodeproj - name: Build iOS Framework run: | ./gradlew :shared:linkDebugFrameworkIosArm64 - name: Run commonTest on iOS Simulator run: | xcodebuild test \ -scheme Shared \ -destination 'platform=iOS Simulator,name=iPhone 15,OS=latest' \ -derivedDataPath build/DerivedData |
- Android ジョブ は
ubuntu-latest(Android SDK が公式イメージに含まれる)で実行。 - iOS ジョブ は
macos-latest(Xcode 15 がプリインストール)を使用し、SPM の依存解決とシミュレータテストを同時に走らせます。
5. デプロイ手順(エミュレータ / シミュレータ)
| プラットフォーム | 手順 |
|---|---|
| Android | Android Studio の Run ボタン → エミュレータが起動し、app がインストールされます。Gradle タスク assembleDebug が内部で呼び出されています。 |
| iOS (CocoaPods) | Xcode で MyApp (iOS) スキームを選択 → ⌘R でシミュレータにビルド・実行。CocoaPods が生成した Shared.framework が自動リンクされます。 |
| iOS (SPM) | 同様に Xcode のスキームから Run → SPM が提供するバイナリターゲットが組み込まれた状態でアプリが起動します。 |
Tip: 両プラットフォームで同時にデバッグしたい場合は、Android Studio では
Run > Edit Configurationsに iOS 用の「External Tool」設定(xcodebuild)を追加すると、IDE から一括実行が可能です。
6. まとめと次のステップ
- 環境構築 – JDK 17 と Android Studio Giraffe をインストールし、Kotlin Multiplatform プラグインを有効化。
- 雛形生成 – Wizard が作る
commonMain / androidMain / iosMainの 3 層構造をベースに開発開始。 - 依存管理 – Ktor + kotlinx‑serialization を共通で、プラットフォーム固有は OkHttp/Darwin を選択。
- iOS 統合 – プロジェクトの成熟度やチーム方針に合わせて CocoaPods または Swift Package Manager のどちらかを採用し、具体的手順通りに設定。
- テスト・CI –
commonTestでユニットテストを共通化し、GitHub Actions に Android と iOS 両方のビルド・テストジョブを追加。
次に挑戦したいこと
- Compose Multiplatform を導入して UI 層も共有
- SQLDelight や Realm Kotlin SDK でローカルデータベースをマルチプラットフォーム化
- Firebase の KMP 対応ライブラリ(Authentication, Firestore)でバックエンド統合
参考リンク(1 回だけ記載)
| 内容 | URL |
|---|---|
| Android Studio ダウンロード | https://developer.android.com/studio |
| Kotlin Multiplatform 公式ガイド | https://kotlinlang.org/docs/multiplatform.html |
| Ktor クライアントドキュメント | https://ktor.io/docs/client-index.html |
| CocoaPods 公式サイト | https://cocoapods.org/ |
| Swift Package Manager 公式リファレンス | https://developer.apple.com/documentation/swift_packages |
| GitHub Actions の Android 設定例 | https://github.com/actions/setup-java |
以上が、2024 年時点の最新安定版ツールチェーンを用いた Kotlin Multiplatform プロジェクト構築から CI/CD まで のフルガイドです。ぜひ手元で試してみてください!