0Pricing
Kotlin Academy · レッスン

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 Logger

iosMain: 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 here

iOSターゲットの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.kt

CocoaPods / 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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. KMPプロジェクト構造:commonMain、androidMain、iosMain
  2. プラットフォームAPI向けexpect/actual機構
  3. Repository層とUse Case層の共有
  4. KoinによるKMPの依存性注入
← Kotlin Academyに戻る