KMPプロジェクト構造:commonMain、androidMain、iosMain
ソースセットの階層と、ターゲット間でコードを共有する方法を理解します。
「KMPプロジェクト構造:commonMain、androidMain、iosMain」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。
KMPとは
Kotlin Multiplatform(KMP)を使うと、JVM、Android、iOS(Kotlin/Native経由)、JS向けにコンパイルできる共有Kotlinコードを記述できます。プラットフォーム固有のコードは、別々のソースセットに配置します。
// Typical KMP module structure:
// shared/
// src/
// commonMain/kotlin/ <- shared code
// androidMain/kotlin/ <- Android-only
// iosMain/kotlin/ <- iOS-only
// commonTest/kotlin/ <- shared tests
fun main() { println("KMP: one codebase, many targets") }ソースセットの階層
ソースセットは階層を形成します。commonMainがルートで、androidMainとiosMainはそこに依存します。commonMainのコードは、すべてのターゲットから参照できます。
// build.gradle.kts (Kotlin DSL)
kotlin {
androidTarget()
iosX64()
iosArm64()
iosSimulatorArm64()
sourceSets {
val commonMain by getting {
dependencies { /* shared deps */ }
}
val androidMain by getting
val iosMain by getting
}
}commonMain: 共有ロジック
ビジネスロジック、ドメインモデル、リポジトリ、ユースケースをcommonMainに配置します。このコードはすべてのターゲット向けにコンパイルされます。
// commonMain/kotlin/com/example/domain/User.kt
data class User(val id: String, val name: String, val email: String)
// commonMain/kotlin/com/example/repository/UserRepository.kt
interface UserRepository {
suspend fun getUser(id: String): User?
suspend fun saveUser(user: User)
}androidMain: Android固有のコード
androidMainではAndroid SDKのクラスを使用できます。一般的な用途は、expect/actual宣言のAndroid固有の実装です。
// androidMain/kotlin/com/example/platform/PlatformLogger.kt
import android.util.Log
class AndroidLogger : Logger {
override fun log(msg: String) = Log.d("App", msg)
}
// androidMain/kotlin/com/example/di/PlatformModule.kt
// Koin or Hilt module that binds AndroidLogger to LoggeriosMain: iOS固有のコード
iosMainでは、Kotlin/Nativeの相互運用機能を通じてAppleのフレームワークにアクセスできます。expect/actual APIのiOS実装に使用します。
// iosMain/kotlin/com/example/platform/PlatformLogger.kt
import platform.Foundation.NSLog
class IosLogger : Logger {
override fun log(msg: String) = NSLog(msg)
}
// iOS uses Kotlin/Native runtime; no JVM hereiOSターゲットのGradle設定
iOSでは通常、3つのターゲットを宣言します。x64(Intel上のシミュレーター)、arm64(実機)、simulatorArm64(Apple Silicon上のシミュレーター)です。
// build.gradle.kts
kotlin {
iosX64()
iosArm64()
iosSimulatorArm64()
sourceSets {
val iosMain by creating {
dependsOn(commonMain.get())
}
val iosX64Main by getting { dependsOn(iosMain) }
val iosArm64Main by getting { dependsOn(iosMain) }
val iosSimulatorArm64Main by getting { dependsOn(iosMain) }
}
}commonMainの共有依存関係
共有依存関係(Ktor、SQLDelight、kotlinx.serialization、Koin)をcommonMainに追加します。プラットフォーム固有のドライバーは、各プラットフォームのソースセットに配置します。
// commonMain dependencies example:
// implementation("io.ktor:ktor-client-core:2.3.0")
// implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
// implementation("io.insert-koin:koin-core:3.4.0")
// androidMain:
// implementation("io.ktor:ktor-client-okhttp:2.3.0")
// iosMain:
// implementation("io.ktor:ktor-client-darwin:2.3.0")commonTest: 共有テスト
commonTestのテストは、すべてのターゲットで実行されます。Kotlin testライブラリを使用し、共有ビジネスロジックに対するターゲット非依存のユニットテストを記述します。
// commonTest/kotlin/UserRepositoryTest.kt
import kotlin.test.Test
import kotlin.test.assertEquals
class UserRepositoryTest {
@Test
fun testUserCreation() {
val user = User("1", "Alice", "alice@example.com")
assertEquals("Alice", user.name)
}
}中間ソースセット
一部のターゲット間で共有する中間ソースセットを作成できます。たとえば、すべてのネイティブターゲット向けのnativeMainや、iOSとmacOS向けのappleMainなどです。
// Create appleMain shared between iOS and macOS:
sourceSets {
val appleMain by creating { dependsOn(commonMain.get()) }
val iosMain by getting { dependsOn(appleMain) }
val macosMain by getting { dependsOn(appleMain) }
}プロジェクトのファイル構成
一般的なKMP共有モジュールのディレクトリツリーで、関心ごとを明確に分離した構成です。
// shared/
// build.gradle.kts
// src/
// commonMain/kotlin/
// domain/ User.kt, Post.kt
// repository/ UserRepository.kt
// usecase/ GetUserUseCase.kt
// androidMain/kotlin/
// repository/ RoomUserRepository.kt
// iosMain/kotlin/
// repository/ CoreDataUserRepository.kt
// commonTest/kotlin/ GetUserUseCaseTest.ktCocoaPods / SPMとの統合
KMP GradleプラグインはXCFramework(またはCocoaPods pod)を生成します。これをXcodeプロジェクトに追加すると、共有Kotlinコードがネイティブフレームワークとして公開されます。
// build.gradle.kts for CocoaPods:
kotlin {
cocoapods {
name = "Shared"
version = "1.0"
ios.deploymentTarget = "14.0"
framework { baseName = "Shared" }
}
}
// Run: ./gradlew :shared:podPublishReleaseXCFramework確認問題
共有ビジネスロジック(ドメインモデルやユースケース)は、KMPプロジェクトのどこに配置すべきですか?
まとめ
commonMainには共有ロジック(ドメイン、リポジトリ、ユースケース)を配置します。androidMain/iosMainにはプラットフォーム実装を配置します。commonTestのテストはすべてのターゲットで実行されます。依存関係は、共有APIをcommonMainに、プラットフォームドライバーを各プラットフォームのソースセットに分けて配置します。
よくある質問
「KMPプロジェクト構造:commonMain、androidMain、iosMain」レッスンは無料ですか?
はい。「KMPプロジェクト構造:commonMain、androidMain、iosMain」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「KMPプロジェクト構造:commonMain、androidMain、iosMain」で何を学びますか?
ソースセットの階層と、ターゲット間でコードを共有する方法を理解します。 ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「KMPプロジェクト構造:commonMain、androidMain、iosMain」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- KMPプロジェクト構造:commonMain、androidMain、iosMain
- プラットフォームAPI向けexpect/actual機構
- Repository層とUse Case層の共有
- KoinによるKMPの依存性注入