Swift package エクスポートの設定
- 最終的なアプリケーションのコードベースと共通のコードベースを分離したい。
- ローカルマシンで iOS をターゲットとした Kotlin Multiplatform プロジェクトをすでにセットアップしている。
- iOS プロジェクトの依存関係の管理に Swift Package Manager を使用している。
Apple ターゲット向けの Kotlin/Native 出力を、Swift Package Manager (SwiftPM) の依存関係として利用できるように設定できます。
iOS ターゲットを持つ Kotlin Multiplatform プロジェクトを想定してください。この iOS バイナリを、ネイティブの Swift プロジェクトで作業している iOS 開発者が依存関係として利用できるようにしたい場合があります。Kotlin Multiplatform のツールを使用すると、Xcode プロジェクトにシームレスに統合できるアーティファクトを提供できます。
このチュートリアルでは、Kotlin Gradle プラグインを使用して XCFrameworks を構築することで、これを実現する方法を説明します。
リモート統合のセットアップ
フレームワークを利用可能にするには、次の 2 つのファイルをアップロードする必要があります:
- XCFramework を含む ZIP アーカイブ。これを、直接アクセス可能な便利なファイルストレージ(例えば、アーカイブを添付した GitHub リリースの作成、Amazon S3、または Maven など)にアップロードする必要があります。ワークフローに最も統合しやすいオプションを選択してください。
- パッケージを記述する
Package.swiftファイル。これを別の Git リポジトリにプッシュする必要があります。
プロジェクト構成のオプション
このチュートリアルでは、XCFramework をバイナリとして任意のファイルストレージに保存し、Package.swift ファイルを別の Git リポジトリに保存します。
ただし、プロジェクトを異なる方法で構成することもできます。Git リポジトリの構成については、以下のオプションを検討してください:
Package.swiftファイルと、XCFramework にパッケージ化されるコードを別々の Git リポジトリに保存する。これにより、Swift マニフェストをプロジェクト自体とは別にバージョン管理できるようになります。これが推奨されるアプローチです。スケーリングが可能で、一般的にメンテナンスが容易になります。Package.swiftファイルを Kotlin Multiplatform のコードと同じ場所に置く。これはより直接的なアプローチですが、この場合、Swift パッケージとコードが同じバージョニングを使用することに注意してください。SwiftPM はパッケージのバージョニングに Git タグを使用するため、プロジェクトで使用されるタグと競合する可能性があります。Package.swiftファイルを利用側のプロジェクトのリポジトリ内に保存する。これにより、バージョニングやメンテナンスの問題を回避できます。ただし、このアプローチは、利用側プロジェクトのマルチリポジトリ SwiftPM セットアップや、さらなる自動化において問題を引き起こす可能性があります:- マルチパッケージプロジェクトでは、プロジェクト内での依存関係の競合を避けるために、1 つのコンシューマーパッケージのみが外部モジュールに依存できます。そのため、Kotlin Multiplatform モジュールに依存するすべてのロジックは、特定のコンシューマーパッケージにカプセル化される必要があります。
- 自動化された CI プロセスを使用して Kotlin Multiplatform プロジェクトを公開する場合、このプロセスには更新された
Package.swiftファイルを利用側のリポジトリに公開する工程を含める必要があります。これにより、利用側リポジトリでの更新の競合が発生する可能性があり、CI におけるそのようなフェーズの維持が困難になる場合があります。
マルチプラットフォームプロジェクトの設定
以下の例では、Kotlin Multiplatform プロジェクトの共通コードがローカルの shared モジュールに保存されています。プロジェクトの構造が異なる場合は、コードやパスの例にある "shared" を実際のモジュール名に置き換えてください。
XCFramework の公開を設定するには:
shared/build.gradle.kts設定ファイルを更新し、iOS ターゲットリストにXCFrameworkの呼び出しを追加します:kotlinimport org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework kotlin { // 他の Kotlin Multiplatform ターゲット // ... // 利用側のプロジェクトでインポートされるモジュールの名前 val xcframeworkName = "Shared" val xcf = XCFramework(xcframeworkName) listOf( iosArm64(), iosSimulatorArm64(), ).forEach { it.binaries.framework { baseName = xcframeworkName // フレームワークを一意に識別するための CFBundleIdentifier を指定 binaryOption("bundleId", "org.example.${xcframeworkName}") xcf.add(this) isStatic = true } } //... }フレームワークを作成するための Gradle タスクを実行します:
shell./gradlew :shared:assembleSharedXCFramework生成されたフレームワークは、プロジェクトディレクトリ内の
shared/build/XCFrameworks/release/Shared.xcframeworkフォルダとして作成されます。Compose Multiplatform プロジェクトを使用している場合は、次の Gradle タスクを使用してください:
shell./gradlew :sharedUI:assembleSharedXCFramework生成されたフレームワークは
sharedUI/build/XCFrameworks/release/Shared.xcframeworkフォルダにあります。
XCFramework と Swift パッケージマニフェストの準備
Shared.xcframeworkフォルダを ZIP ファイルに圧縮し、生成されたアーカイブのチェックサムを計算します。例:swift package compute-checksum Shared.xcframework.zipZIP ファイルを選択したファイルストレージにアップロードします。ファイルはダイレクトリンクでアクセスできる必要があります。例えば、GitHub のリリース機能を使用する方法は以下の通りです:
GitHub リリースへのアップロード
- GitHub にアクセスし、アカウントにログインします。
- リリースを作成したいリポジトリに移動します。
- 右側の Releases セクションで、Create a new release リンクをクリックします。
- リリースの情報を入力し、新しいタグを追加または作成し、リリースのタイトルを指定して説明を書きます。
下部にある Attach binaries by dropping them here or selecting them フィールドから、XCFramework の ZIP ファイルをアップロードします:

- Publish release をクリックします。
リリースの Assets セクションで、ZIP ファイルを右クリックし、ブラウザで Copy link address(または同様のオプション)を選択します:

[推奨] リンクが機能し、ファイルがダウンロードできることを確認します。ターミナルで次のコマンドを実行します:
nonecurl <アップロードされた XCFramework ZIP ファイルへのダウンロード可能なリンク>任意のディレクトリを選択し、ローカルに以下のコードを含む
Package.swiftファイルを作成します:Swift// swift-tools-version:5.3 import PackageDescription let package = Package( name: "Shared", platforms: [ .iOS(.v14), ], products: [ .library(name: "Shared", targets: ["Shared"]) ], targets: [ .binaryTarget( name: "Shared", url: "<アップロードされた XCFramework ZIP ファイルへのリンク>", checksum:"<ZIP ファイルに対して計算されたチェックサム>") ] )urlフィールドに、XCFramework を含む ZIP アーカイブへのリンクを指定します。[推奨] 生成されたマニフェストを検証するには、
Package.swiftファイルがあるディレクトリで次のシェルコマンドを実行します:shellswift package reset && swift package show-dependencies --format jsonマニフェストが正しい場合、出力にはエラーが表示されないか、ダウンロードと解析の成功結果が表示されます。
Package.swiftファイルをリモートリポジトリにプッシュします。パッケージのセマンティックバージョンを含む Git タグを作成してプッシュしてください。
パッケージ依存関係の追加
両方のファイルにアクセスできるようになったので、既存のクライアント iOS プロジェクトに作成したパッケージへの依存関係を追加するか、新しいプロジェクトを作成できます。パッケージ依存関係を追加するには:
Xcode で、File | Add Package Dependencies を選択します。
検索フィールドに、
Package.swiftファイルが含まれている Git リポジトリの URL を入力します:
Add package ボタンをクリックし、パッケージの製品と対応するターゲットを選択します。
Swift パッケージを作成している場合、ダイアログが異なります。この場合は、Copy package ボタンをクリックします。これにより、
.packageの行がクリップボードにコピーされます。この行を自身のPackage.swiftファイルの Package.Dependency ブロックに貼り付け、適切なTarget.Dependencyブロックに必要な製品を追加してください。
セットアップの確認
すべてが正しく設定されているかを確認するために、Xcode でインポートをテストします:
プロジェクトで、UI ビューファイル(例:
ContentView.swift)に移動します。コードを次のスニペットに置き換えます:
Swiftimport SwiftUI import Shared struct ContentView: View { var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world! \(Shared.Platform_iosKt.getPlatform().name)") } .padding() } } #Preview { ContentView() }ここでは、
SharedXCFramework をインポートし、それを使用してTextフィールドにプラットフォーム名を取得しています。プレビューが新しいテキストで更新されることを確認します。
複数のモジュールを XCFramework としてエクスポートする
複数の Kotlin Multiplatform モジュールのコードを iOS バイナリとして利用可能にするには、これらのモジュールを単一のアンブレラ (umbrella) モジュールに統合します。その後、そのアンブレラモジュールの XCFramework をビルドしてエクスポートします。
例えば、network モジュールと database モジュールがあり、これらを together モジュールに統合する場合:
together/build.gradle.ktsファイルで、依存関係とフレームワークの構成を指定します:kotlinkotlin { val frameworkName = "together" val xcf = XCFramework(frameworkName) listOf( iosArm64(), iosSimulatorArm64() ).forEach { iosTarget -> // 上記の例と同様ですが、 // 依存関係のエクスポート呼び出しが追加されています iosTarget.binaries.framework { export(projects.network) export(projects.database) baseName = frameworkName xcf.add(this) } } // 内部モジュールをエクスポートするために、依存関係を "api"("implementation" ではなく)として設定 sourceSets { commonMain.dependencies { api(projects.network) api(projects.database) } } }含まれる各モジュールには、iOS ターゲットが設定されている必要があります。例:
kotlinkotlin { android { //... } iosArm64() iosSimulatorArm64() //... }togetherフォルダ内に空の Kotlin ファイル(例:together/src/commonMain/kotlin/Together.kt)を作成します。これは、現在の Gradle スクリプトでは、エクスポートされたモジュールにソースコードが含まれていないとフレームワークを組み立てられないための回避策です。フレームワークを組み立てる Gradle タスクを実行します:
shell./gradlew :together:assembleTogetherReleaseXCFramework前のセクションの手順に従って
together.xcframeworkを準備します:アーカイブの作成、チェックサムの計算、アーカイブされた XCFramework のファイルストレージへのアップロード、Package.swiftファイルの作成とプッシュを行います。
これで、Xcode プロジェクトに依存関係をインポートできます。import together ディレクティブを追加すると、Swift コードで network モジュールと database モジュールの両方のクラスをインポートして利用できるようになります。
