Swift Package ManagerでXCFramework形式のFirebaseを使って、ビルド時間を大幅に短縮する
Firebaseライブラリでは、XCFramework形式のバイナリビルドが提供されています。バイナリビルドを使うと、ライブラリをビルドしないためアプリ全体のビルド時間を削減できます。調査した結果、Swift Package Manager(SPM)でバージョン管理しつつバイナリ版のFirebaseライブラリを利用できたので、その方法を紹介します。
結論
- Xcodeの
Add Packages
で https://github.com/akaffenberger/firebase-ios-sdk-xcframeworks を追加します[1]。バージョニングはfirebaseと同じものが使えます。 - ターゲットのBuild Settingsから、Other Linker Flagsに
-ObjC
を入れます[2]。
なお、FirebaseFirestoreSwiftなど、Beta版の機能はバイナリに含まれていないので利用できません。
→ (2022.05.13追記) 5/3にリリースされたv9.0.0で(サービス名)Swift
パッケージがGAになり、FirebaseInAppMessagingSwift
を除くライブラリのバイナリも利用できるようになりました!これにより、バイナリ版を利用した上でasync/awaitを使いつつfirebaseの各機能を利用できるようになります[3]。
前提
Firebase SDK for iOSでは、XCFramework形式でビルド済みライブラリが提供されています。公式リポジトリのreleasesページにて、Firebaseの全サービスのXCFrameworkをダウンロードできます。
このzipファイルを開くと、以下のようになっています。
- Firebase.h: 各サービスimport用ヘッダ定義
- module.modulemap: modulemap定義
- NOTICES: 依存ライブラリのオープンソースライセンス一覧
- Firebase***: サービスごとのXCFramework一式。XCFrameworkごとにInfo.plistとアーキテクチャごとのXCFramworkの実体を持つ。
これらのファイルをプロジェクトに導入することで、Firebaseのサービスで利用できるようになります。
XCFrameworkを使う方法
以下の2種類があります。
- firebase-ios-sdk-xcframeworksライブラリを使う方法
- (自前でライブラリを依存させる)
2021年12月頃に1.が開発され、SPM上でバージョン管理ができるようになっています。ライブラリ管理のしやすさとビルド時間の削減を両立できておすすめです。
1. firebase-ios-sdk-xcframeworksライブラリを使う方法
akaffenberger氏が提供しているfirebase-ios-sdk-xcframeworksライブラリを利用します。本ライブラリはGitHub Actionで大体2時間ごとにfirebase公式の最新リリースを見に行くようになっており、最新のバイナリのリリースがcommitされる仕組みとなっています。
上記仕組みのため、SPMで上記リポジトリを登録することで、firebaseの最新バイナリを利用できます。すでにSPMでfirebase-ios-sdkを登録している場合は、そちらを削除して上記リポジトリを登録するとOKです。
また、プロジェクトのBuild Settingsから、Other Linker Flagに-ObjC
を入れるようにしてください。このフラグがないと、ビルドは通るものの実行時に結果が返ってこないなど、Firebaseライブラリが正常に動作しません。
2. (おまけ) 自前でライブラリを依存させる
どのようにすればFirebaseのXCFrameworkを自前で使えるかどうか、具体例を記載しています。通常の用途では2.の方法は管理が煩雑になるものの、参考として記載しています。
サンプルコード
公式のXCFrameworkについて、bin/pull_firebase_xcframeworks.shによりダウンロード・抽出しています。抽出したXCFrameworkはxcframeworks/firebase下に自動的に同期(rsync)されるため、後はプロジェクト側で下記の設定などを行えばOKです。
プロジェクトの設定
以下、初回導入時のみ実施
- USER_HEADER_SEARCH_PATHS = "xcframeworks/firebase/**" を足す (firebase.h, modle.modulemapを認識させるため)
- Other Linker Flagsに
-ObjC
フラグを追加
ライブラリにアップデートがある、もしくは利用サービスが変わる度に実施
- xcframeworks/firebase/をXcodeにドラッグアンドドロップする
XCFramework抽出スクリプト
#!/bin/bash
# *** CONFIG ***
VERSION="v8.15.0"
DEPENDENCIES=(
"FirebaseAnalytics"
"FirebaseAuth"
"FirebaseFirestore"
"FirebaseFunctions"
"FirebaseStorage"
)
EXCLUDE_ARCHES=(
"tvos"
"macos"
"maccatalyst"
)
REQUIRED_FILES=(
"Firebase.h"
"module.modulemap"
)
# *** CODES ***
TARGET_PATH="../xcframeworks/Firebase"
if [ -d $TARGET_PATH ]; then
rm -r $TARGET_PATH
fi
# fetch xcframeworks
wget https://github.com/firebase/firebase-ios-sdk/releases/download/$VERSION/Firebase.zip -O Firebase.zip
unzip Firebase.zip
rm Firebase.zip
#copy modulemap, header
mkdir $TARGET_PATH
for dep in ${REQUIRED_FILES[@]};
do
cp Firebase/$dep ${TARGET_PATH}/$dep
done
# find all xcworkspaces in DEPENDENCIES
greps="grep"
for dep in ${DEPENDENCIES[@]};
do
greps="$greps -e $dep"
done
xcframeworks=$(find Firebase -name "*.xcframework" -maxdepth 2 | $greps)
# find all xcworkspaces in DEPENDENCIES
exclude_arch_args=""
for arch in ${EXCLUDE_ARCHES[@]};
do
exclude_arch_args="$exclude_arch_args --exclude=*${arch}*"
done
# copy xcworkspaces but not duplicated (their version must be same)
copied_xcframeworks=""
for xcframework_path in ${xcframeworks[@]};
do
xcframework_name=$(basename $xcframework_path)
if [[ ! "$copied_xcframeworks" == *"$xcframework_name"* ]]; then
copied_xcframeworks="$copied_xcframeworks $xcframework_name"
rsync -a $exclude_arch_args $xcframework_path $TARGET_PATH
fi
done
# clean up
rm -r Firebase
echo "Firebase dependency injected."
本コードの処理の流れは以下です。
- firebase-ios-sdkのXCFrameworkが入ったzipを取得、解凍する
- module.modulemap, Firebase.hをプロジェクトに追加する
- 必要なFirebase系ライブラリについて、依存するXCFrameworkの一覧を取得
- XCFrameworkをプロジェクトのxcframeworks/Firebase下にコピーする。ただし、すでにコピーしたXCFrameworkはコピーしない※
- 一時ファイルの削除
※ 同一firebaseバージョンにおいてXCFrameworkは同一なので、どれか1つだけをコピーすればOKです
このコードについて、以下の設定があります。必要に応じ書き換えることで、コピーされるXCFrameworksをアップデートor整理することができます。
- VERSION: Firebaseのバージョン
- DEPENDENCIES: Firebaseのうち、どのサービスを使うか
- EXCLUDE_ARCHES: 除外するXCFrameworkのアーキテクチャ(tvos, macos, iosなど)。部分一致で判定する
-
有志で開発されたライブラリになるので、Firebase公式のサポートが必要な場合は適用が困難となります。 ↩︎
-
Firebase Apple SDK Release Notes Version 9.0.0 - May 3, 2022 ↩︎
Discussion