SDK開発をしていると、秘伝のソースコード自体は秘匿したいけど、SDKとして配布したいケースがあると思います。それも、定番のライブラリ管理ツールを使ってインストールできればディベロッパーフレンドリーですよね。
そんな制約のあるライブラリも Xcode 12 + XCFramework を使えば簡単に配布できます。
準備するもの
- ver.12以降のXcode
- Githubのパブリックリポジトリ(ライブラリ配布用)
XCFramework とは
XCFrameworkは、Xcodeによって作成された配布可能なバイナリパッケージ。
xcodebuild
コマンドで生成でき、わざわざlipo
をしなくてもユニバーサルフレームワーク化できる。
https://help.apple.com/xcode/mac/11.4/#/dev6f6ac218b
ユニバーサルフレームワークとは...?
XCFramework をつくる
今回はiOS向けに配布する想定でサンプルとして、今日のラッキーカラーを占うTodayColor
フレームワーク、ラッキーナンバーを占うTodayNumber
フレームワークをそれぞれ作ってみました。
これをXCFrameworkにしていきます。
XCArchive の作成
Simulatorと実機デバイス用にXCArchiveを作成します。
開発しているプロジェクトの構成に合わせてビルドコマンドは変えてください✌️😸
https://help.apple.com/xcode/mac/11.4/#/dev544efab96
各オプションやXCFramework対応についてはこちらの@ArimeさんのQiitaがとても参考になりました🙇♂️ありがとうございました。
Simulator 用の XCArchive を作成
$ xcodebuild \
'ENABLE_BITCODE=YES' \
'BITCODE_GENERATION_MODE=bitcode' \
'OTHER_CFLAGS=-fembed-bitcode' \
'BUILD_LIBRARY_FOR_DISTRIBUTION=YES' \
'SKIP_INSTALL=NO' \
archive \
-project Today.xcodeproj \
-scheme 'TodayColor' \
-destination 'generic/platform=iOS Simulator' \
-configuration 'Release' \
-archivePath 'build/TodayColor-iphonesimulator.xcarchive'
実機デバイス用の XCArchive を作成
$ xcodebuild \
'ENABLE_BITCODE=YES' \
'BITCODE_GENERATION_MODE=bitcode' \
'OTHER_CFLAGS=-fembed-bitcode' \
'BUILD_LIBRARY_FOR_DISTRIBUTION=YES' \
'SKIP_INSTALL=NO' \
archive \
-project Today.xcodeproj \
-scheme 'TodayColor' \
-destination 'generic/platform=iOS' \
-configuration 'Release' \
-archivePath 'build/TodayColor-iphoneos.xcarchive'
これで、Simulatorと実機デバイス、それぞれのXCArchiveが生成されました。
- TodayColor-iphonesimulator.xcarchive
- TodayColor-iphoneos.xcarchive
XCFramework の作成
前述で作成したXCArchiveを一つにまとめていきます。
$ xcodebuild \
-create-xcframework \
-framework 'build/TodayColor-iphoneos.xcarchive/Products/Library/Frameworks/TodayColor.framework' \
-framework 'build/TodayColor-iphonesimulator.xcarchive/Products/Library/Frameworks/TodayColor.framework' \
-output 'build/TodayColor.xcframework'
はい、これでユニバーサルなXCFrameworkが完成です。
今回はTodayColor
とTodayNumber
の2つフレームワークを作ったので、同様の手順でもう一つXCFrameworkを作りました。
Swift Package Manager で配布
ここからは、開発用とは別の配布用リポジトリのディレクトリで作業していきます。
間違えてプライベートリポジトリのコードをpush
しないよう要注意🙀
git
操作については既存リポジトリを利用するケースなどあると思いますので、適宜読替をお願いします。
今回は配布用に、下記のGithubのパブリックリポジトリを作りました。
Swift Package を作成
- Xcodeを開く
- File > New > Swift Package...
- 名前をつけてSwift Packageを作成します
Package.swift
を編集
上記で作成した.swiftpm/xcode/package.xcworkspace
を開き、Package.swift
を編集していきます。
products
> library
サンプルではパッケージはTodaySDK
一つですが
- ラッキーカラーを占いたい場合は
TodayColor
フレームワーク - ラッキーナンバーを占いたい場合は
TodayNumber
フレームワーク
をディベロッパー側で選択できるよう、products
のlibrary
を分けて配布します。
name: "TodaySDK",
products: [
.library(
name: "TodayColor",
targets: ["TodayColor"]),
.library(
name: "TodayNumber",
targets: ["TodayNumber"])
]
targets
今回はバイナリをGithub上でホストするため、binaryTarget
を指定します。
また、XCFramework は後述の作業でPackage.swift
と同じ階層に配置するので、下記のように指定をします。
targets: [
.binaryTarget(name: "TodayColor",
path: "TodayColor.xcframework"),
.binaryTarget(name: "TodayNumber",
path: "TodayNumber.xcframework"),
]
Package.swift
コード全体
XCFramework を配布用リポジトリに追加
XCFrameworkの作成 項目で作成したXCFrameworkを配布リポジトリに追加します。
$ cd path/to/repository/for/distribtion
$ cp -r path/to/.xcframework ./
XCFramework と Swift Package をgit commit
& push
ここまで完了したら、作成した Swift Package と XCFramework をgit commit
& push
します。
$ git commit . -m "Add Swift Package & XCFramework"
$ git push origin main
タグ付け & リリース
$ git tag 1.0.0
$ git push origin 1.0.0
ののち、配布用リポジトリでリリースを行うだけで、Swift Package の公開は完了です👏👏😸
まとめ
Xcode11でSwiftPMが統合されて以降、iOS開発にSwiftPMを使う機会は以前より増えてきたな〜と思います。ライブラリ開発に手をつけるなら、今後、ますます定着するであろうSwiftPMサポートも進めていきたいですね!
SwiftPMのバイナリサポートについては、WWDCのビデオもあります。
8分弱なので気軽に見られておすすめです。
以上です
ありがとうございました。
(番外編)SPMのフレームワークを試す
試しにフレームワークをインストールしてみましょう。
デモプロジェクトを作成し、File > Swift Packages > Add Package Dependency でhttps://github.com/mesummery/TodaySDK
を入力しパッケージを追加します。
最新バージョンが取得できました。
TodayColor
とTodayNumber
も分割できていますね。
import TodayColor
class ViewController: UIViewController {
@IBOutlet weak var colorView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let color = TodayColor.tellMe()
colorView.backgroundColor = color
}
}
問題なくimport
できて、リンクも成功、ビルドもできました👏
Today Color | Today Number |
---|---|