サンプルプロジェクト
どんな状況?
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に対応していないライブラリは既にメンテナンスされていない可能性が高いので、別のライブラリを探したり、自分で書いたりするのも一つの手だと思います。