プラットフォーム間でのコード共有
Kotlin Multiplatformを使用すると、Kotlinが提供するメカニズムを使用してコードを共有できます:
- プロジェクトで使用されるすべてのプラットフォーム間でのコード共有。すべてのプラットフォームに適用される共通のビジネスロジックを共有するために使用します。
- 一部のプラットフォーム間でのコード共有。プロジェクトに含まれる一部(すべてではない)のプラットフォーム間でコードを共有します。階層構造(hierarchical structure)を利用して、類似したプラットフォーム間でコードを再利用できます。
共有コードからプラットフォーム固有のAPIにアクセスする必要がある場合は、Kotlinの期待宣言と実体宣言(expected and actual declarations)のメカニズムを使用してください。
すべてのプラットフォームでのコード共有
すべてのプラットフォームに共通するビジネスロジックがある場合、プラットフォームごとに同じコードを記述する必要はありません。共通ソースセット(common source set)で共有するだけです。
ソースセットの一部の依存関係はデフォルトで設定されています。以下のものについては、手動で dependsOn 関係を指定する必要はありません:
jvmMainやmacosArm64Mainなど、共通ソースセットに依存するすべてのプラットフォーム固有のソースセット。androidMainとandroidUnitTestなど、特定のターゲットのmainソースセットとtestソースセットの間。
共有コードからプラットフォーム固有のAPIにアクセスする必要がある場合は、Kotlinの期待宣言と実体宣言(expected and actual declarations)のメカニズムを使用してください。
類似したプラットフォームでのコード共有
多くの場合、共通のロジックやサードパーティAPIを大量に再利用できる可能性のある、複数のネイティブターゲットを作成する必要があります。
例えば、iOSをターゲットとする一般的なマルチプラットフォームプロジェクトでは、iOS ARM64デバイス用とx64シミュレータ用の2つのiOS関連ターゲットがあります。これらには個別のプラットフォーム固有ソースセットがありますが、実際にはデバイスとシミュレータで異なるコードが必要になることは稀であり、依存関係もほぼ同じです。そのため、iOS固有のコードをそれらの間で共有できます。
明らかに、この構成では、2つのiOSターゲットに対して共有ソースセットを用意し、iOSデバイスとシミュレータの両方に共通するAPIを直接呼び出せるKotlin/Nativeコードを記述できることが望ましいです。
この場合、以下のいずれかの方法で階層構造(hierarchical structure)を使用して、プロジェクト内のネイティブターゲット間でコードを共有できます:
ライブラリでのコード共有およびプラットフォーム固有ライブラリの接続についての詳細をご覧ください。
ライブラリでのコード共有
階層的なプロジェクト構造のおかげで、ライブラリもターゲットのサブセットに対して共通のAPIを提供できます。ライブラリが公開(publish)されると、その中間ソースセット(intermediate source sets)のAPIは、プロジェクト構造に関する情報とともにライブラリアーティファクトに埋め込まれます。このライブラリを使用すると、プロジェクトの中間ソースセットは、各ソースセットのターゲットが利用可能なライブラリのAPIにのみアクセスします。
例えば、kotlinx.coroutines リポジトリの以下のソースセット階層を確認してください:
concurrent ソースセットは runBlocking 関数を宣言し、JVMとネイティブターゲット向けにコンパイルされます。kotlinx.coroutines ライブラリが階層的なプロジェクト構造で更新および公開されると、ライブラリの concurrent ソースセットの「ターゲットシグネチャ(targets signature)」と一致するため、JVMとネイティブターゲット間で共有されているソースセットからそれに依存して runBlocking を呼び出すことができます。
プラットフォーム固有ライブラリの接続
プラットフォーム固有の依存関係に制限されることなく、より多くのネイティブコードを共有するには、Foundation、UIKit、POSIXなどのプラットフォームライブラリ(platform libraries)を使用します。これらのライブラリはKotlin/Nativeに同梱されており、デフォルトで共有ソースセットで利用可能です。
さらに、プロジェクトで Kotlin CocoaPods Gradle プラグインを使用している場合は、cinterop メカニズムを使用して取り込まれたサードパーティのネイティブライブラリを扱うことができます。
