サンプルプロジェクト
どんな状況?
SampleView と言うtargetで Hoge と言うライブラリを使いたい。しかし、HogeはSPM対応していない。
// swift-tools-version: 5.6
import PackageDescription
let package = Package(
name: "Package",
defaultLocalization: "en",
platforms: [.iOS(.v15)],
products: [
.library(
name: "SampleView",
targets: ["SampleView"]),
],
dependencies: [
// SPM対応していない!
// .package(url: "XXXXX", from: "1.0.0"),
],
targets: [
.target(
name: "SampleView",
dependencies: [
// dependenciesに導入できないから使えない!!
// .product(name: "Hoge", package: "Hoge", condition: .when(platforms: [.iOS])),
]
),
]
)
解決策: Carthageで.xcframeworkビルドする
Carthageは.xcframework形式でライブラリをビルドすることができます。
.xcframework形式はPackage.swiftの.binaryTargetを利用することでtargetとして定義できるため、他targetから利用することができます。
Carthageをインストールする方法
Homebrewのインストール
CarthageをインストールするにはHomebrewが必要です。以下でインストールできます。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Carthageのインストール
brew install carthage
Carthageによるビルド
まず、Package 以下にcartfileを作成し、導入したいライブラリを記述します。
cd path/to/Package
touch Cartfile
github "XXX/ライブラリ名"
そして、--use-xcframeworks オプションをつけてビルドします。
carthage bootstrap --platform iOS --cache-builds --use-xcframeworks
これにより、Package/Carthage/Build以下にライブラリ名.xcframeworkが作成されます。
Package.swiftでの利用
Package.swiftで.binaryTargetを用いて先ほど作成したライブラリ名.xcframeworkを参照します。
// swift-tools-version: 5.6
import PackageDescription
let package = Package(
name: "Package",
defaultLocalization: "en",
platforms: [.iOS(.v15)],
products: [
.library(
name: "SampleView",
targets: ["SampleView"]),
],
dependencies: [
],
targets: [
.target(
name: "SampleView",
dependencies: ["ライブラリ名"]),// binaryTargetで定義した物を利用
// carthageで作成した.xcframeworkを参照
.binaryTarget(
name: "ライブラリ名",
path: "./Carthage/Build/ライブラリ名.xcframework")
]
)
以上でSPM対応していないライブラリをSPM Package内で利用することができました。
Carthageにも対応していなかったら?
多少手間ですが、CocoaPodsでソースをDLし、手元で直接xcodebuildすれば同様に.xcframeworkを生成可能です。
ここらへんの記事が参考になるはずです。
まとめ
SPMに対応していないライブラリが存在しているのが原因で、multimodule by SPM の利用ができない方も多いのではないでしょうか?そんな方々の助けになれば幸いです。
(というか、もしかしてもっと簡単な方法あったりしますか...?)
multimodule by SPM、簡単にマルチモジュールを構築できてとても重宝しています。
(Xcodeくんにはもうちょっと頑張って欲しいですが...)
備考
他にも以下のような解決策があります。
SPM対応のPRを投げる
一番簡単でスマートなやり方です。PRがマージされれば通常通りPackage.swiftから利用できます。が、ライブラリのメンテナンスが止まっている場合はこの方法では解決しません。
リポジトリをforkしてSPM対応させる
作業量としては「SPM対応のPRを投げる」と同じですが、「今後このライブラリのメンテナンスは自分でやるんだ!!」と言う強い意志が必要です。
そのライブラリを使うのをやめる
元も子もないですね。しかし、現在SPMに対応していないライブラリは既にメンテナンスされていない可能性が高いので、別のライブラリを探したり、自分で書いたりするのも一つの手だと思います。