Swift package のエクスポート設定
これはリモート統合方式です。以下の条件に当てはまる場合に利用できます。:
- 最終的なアプリケーションのコードベースを共通のコードベースから分離したい場合。
- ローカルマシン上でiOSをターゲットとするKotlin Multiplatformプロジェクトをすでにセットアップしている場合。
- iOSプロジェクトで依存関係を処理するためにSwift package managerを使用している場合。
Appleターゲット用のKotlin/Native出力を、Swift package manager(SPM)の依存関係として利用できるように設定できます。
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パッケージとコードが同じバージョン管理を使用することに注意してください。SPMはパッケージのバージョン管理にGitタグを使用しますが、これはプロジェクトに使用されるタグと競合する可能性があります。 -
Package.swift
ファイルを使用する側のプロジェクトのリポジトリ内に保存します。これにより、バージョン管理とメンテナンスの問題を回避できます。ただし、このアプローチは、使用する側のプロジェクトのマルチリポジトリSPMセットアップや、さらなる自動化で問題が発生する可能性があります。- マルチパッケージプロジェクトでは、1つの使用する側のパッケージのみが外部モジュールに依存できます(プロジェクト内の依存関係の競合を避けるため)。したがって、Kotlin Multiplatformモジュールに依存するすべてのロジックは、特定の使用する側のパッケージにカプセル化する必要があります。
- 自動化されたCIプロセスを使用してKotlin Multiplatformプロジェクトを公開する場合、このプロセスには、更新された
Package.swift
ファイルを使用する側のリポジトリに公開することが含まれます。これにより、使用する側のリポジトリの更新が競合する可能性があり、CIのそのようなフェーズの維持が困難になる可能性があります。
マルチプラットフォームプロジェクトの構成
次の例では、Kotlin Multiplatformプロジェクトの共有コードは、ローカルのshared
モジュールに保存されています。プロジェクトの構成が異なる場合は、コードとパスの例の「shared」をモジュールの名前に置き換えてください。
XCFrameworkの公開を設定するには:
-
shared/build.gradle.kts
構成ファイルを、iOSターゲットリストのXCFramework
呼び出しで更新します。import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework
kotlin {
// Other Kotlin Multiplatform targets
// ...
// Name of the module to be imported in the consumer project
val xcframeworkName = "Shared"
val xcf = XCFramework(xcframeworkName)
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64(),
).forEach {
it.binaries.framework {
baseName = xcframeworkName
// Specify CFBundleIdentifier to uniquely identify the framework
binaryOption("bundleId", "org.example.${xcframeworkName}")
xcf.add(this)
isStatic = true
}
}
//...
} -
Gradleタスクを実行して、フレームワークを作成します。
./gradlew :shared:assembleSharedXCFramework
結果のフレームワークは、プロジェクトディレクトリの
shared/build/XCFrameworks/release/Shared.xcframework
フォルダーとして作成されます。Compose Multiplatformプロジェクトを使用している場合は、次のGradleタスクを使用してください。
./gradlew :composeApp:assembleSharedXCFramework
結果のフレームワークは、
composeApp/build/XCFrameworks/release/Shared.xcframework
フォルダーにあります。
XCFrameworkとSwiftパッケージマニフェストの準備
-
Shared.xcframework
フォルダーをZIPファイルに圧縮し、結果のアーカイブのチェックサムを計算します。例:swift package compute-checksum Shared.xcframework.zip
-
ZIPファイルを選択したファイルストレージにアップロードします。ファイルは、直接リンクでアクセスできる必要があります。たとえば、GitHubのリリースを使用してこれを行う方法は次のとおりです。
GitHubリリースへのアップロード
下部のAttach binaries by dropping them here or selecting themフィールドを使用して、XCFrameworkを含むZIPファイルをアップロードします。

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

-
[推奨] リンクが機能し、ファイルをダウンロードできることを確認します。ターミナルで、次のコマンドを実行します。
curl <ダウンロード可能なXCFramework ZIPファイルへのリンク>
-
任意のディレクトリを選択し、次のコードで
Package.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
ファイル付き:swift 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
)に移動します。 -
コードを次のスニペットに置き換えます。
import 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()
}ここでは、
Shared
XCFrameworkをインポートし、それを使用してText
フィールドでプラットフォーム名を取得します。 -
プレビューが新しいテキストで更新されていることを確認します。
複数のモジュールをXCFrameworkとしてエクスポートする
複数のKotlin MultiplatformモジュールのコードをiOSバイナリとして利用できるようにするには、これらのモジュールを単一のアンブレラモジュールに結合します。次に、このアンブレラモジュールのXCFrameworkを構築してエクスポートします。
たとえば、network
モジュールとdatabase
モジュールがあり、これらをtogether
モジュールに結合するとします。
-
together/build.gradle.kts
ファイルで、依存関係とフレームワーク構成を指定します。kotlin {
val frameworkName = "together"
val xcf = XCFramework(frameworkName)
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach { iosTarget `->`
// Same as in the example above,
// with added export calls for dependencies
iosTarget.binaries.framework {
export(projects.network)
export(projects.database)
baseName = frameworkName
xcf.add(this)
}
}
// Dependencies set as "api" (as opposed to "implementation") to export underlying modules
sourceSets {
commonMain.dependencies {
api(projects.network)
api(projects.database)
}
}
} -
含まれる各モジュールには、そのiOSターゲットが構成されている必要があります。例:
kotlin {
androidTarget {
//...
}
iosX64()
iosArm64()
iosSimulatorArm64()
//...
} -
together
フォルダー内に空のKotlinファイルを作成します。たとえば、together/src/commonMain/kotlin/Together.kt
です。 これは回避策です。エクスポートされたモジュールにソースコードが含まれていない場合、Gradleスクリプトは現在フレームワークをアセンブルできません。 -
フレームワークをアセンブルするGradleタスクを実行します。
./gradlew :together:assembleTogetherReleaseXCFramework
-
前のセクションの手順に従って、
together.xcframework
を準備します。アーカイブし、チェックサムを計算し、アーカイブされたXCFrameworkをファイルストレージにアップロードし、Package.swift
ファイルを作成してプッシュします。
これで、依存関係をXcodeプロジェクトにインポートできます。import together
ディレクティブを追加すると、
network
モジュールとdatabase
モジュールの両方のクラスをSwiftコードにインポートできるようになります。