はじめに
Swiftのマルチモジュール構成でFirebaseを使用する際、通常のシングルモジュールとは異なる設定が必要になります。
本記事では、Swift Package Manager(SPM)を使用したマルチモジュール環境でFirebase AnalyticsとCrashlyticsを導入する際の実装手順と、筆者が遭遇した懸念点について解説します。
想定する読者
- Swiftのマルチモジュール構成の基本を理解している方
- Firebaseの基本的な使い方を知っている方
- Swift Package Managerの基礎知識がある方
実装手順
1. Firebaseの登録
Firebase コンソールでのプロジェクト作成、GoogleService-Info.plist のダウンロードなどは、既存の記事が多数あるため割愛します。
2. Package.swiftへの依存関係追加
モジュール側の Package.swift にFirebase SDKを追加します。
let package = Package(
name: "YourModule",
platforms: [.iOS(.v17)],
products: [
.library(
name: "YourModule",
targets: ["YourModule"]
),
],
dependencies: [
.package(url: "https://github.com/firebase/firebase-ios-sdk.git", .upToNextMajor(from: "10.4.0")),
],
targets: [
.target(
name: "YourModule",
dependencies: [
.product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
.product(name: "FirebaseAnalytics", package: "firebase-ios-sdk"),
.product(name: "FirebaseCrashlytics", package: "firebase-ios-sdk"),
]
),
]
)
詳細はFirebase公式ドキュメント1を参照してください。
※ 公式サンプルコードでは、非推奨の呼び出し方2をしているので若干差分があります。
3. @_exported import でメインアプリからアクセス可能にする
これにより、メインアプリ側でimport FirebaseCoreを使用できるようになります。
複数のモジュールでFirebaseを使用する場合、追加で定義する必要があります。
@_exported import FirebaseCore
/// 他モジュールでもFirebaseを使用する場合
@_exported import FirebaseAuth
4. AppDelegateでFirebaseを初期化
Firebaseの初期化は、マルチモジュール側でも可能ですが、AppDelegateから呼び出します。
import UIKit
import SwiftUI
import FirebaseCore
@main
struct YourProjectApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
WindowGroup {
AppRootView()
}
}
}
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
FirebaseApp.configure()
return true
}
}
5. モジュール側でAnalytics・Crashlyticsを呼び出す
モジュール側のコードで、通常通りFirebase AnalyticsやCrashlyticsを使用できます。
import SwiftUI
import FirebaseAnalytics
import FirebaseCrashlytics
import FirebaseAuth
public struct AppRootView: View {
// ...
func trackEvent() {
Analytics.logEvent("custom_event", parameters: nil)
}
func triggerTestCrash() {
// テスト用: 意図的にクラッシュさせる
fatalError("Test crash for Crashlytics")
}
}
6. Build PhaseとBuild Settingsの設定
Build Settingsの内容は、Crashlyticsのドキュメント3にまとめられているので、詳細は割愛します。
以下の設定だけでは不十分1で、input Filesの追加4も必要となります。
${BUILD_DIR%Build/*}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run
懸念点・未解決事項
実装を進める中で、以下の点について公式ドキュメントでの明確な記載が見つからず、対応を保留しています。
1. .dynamic リンクタイプの必要性
一部のFirebase関連の記事では、Package.swift の targets 設定に .dynamic タイプを指定する例が見られます。
.target(
name: "YourModule",
type: .dynamic, // これが必要かどうか不明
dependencies: [...]
)
現状の対応
公式ドキュメントに明記がないため、追加していません。
動作には問題ありませんが、もし詳しい方がいらっしゃれば情報提供いただけると幸いです。
2. Build Phase > Run Script > Input FilesへのdSYM追加
Crashlyticsを使用する際、通常はメインアプリのdSYMファイルをアップロードするためのRun Scriptを設定します。
マルチモジュール側のdSYMファイルも Input Files に追加すべきかどうかは、公式ドキュメントに記載が見つかりませんでした。
現状の対応
マルチモジュール側のdSYMは追加していません。
Crashlyticsのクラッシュレポートは正しく動作していますが、モジュール側でのクラッシュのシンボリケーションに影響がある可能性があります。
まとめ
Swiftのマルチモジュール環境でFirebaseを導入する際の基本的な手順をまとめました。
.dynamic タイプやdSYMの扱いなど、公式ドキュメントに明記されていない部分もあり、引き続き情報収集が必要です。
参考リンク
- Firebase Analytics - スタートガイド
- Firebase Crashlytics - スタートガイド
- Firebaseの依存関係の課題について
- マルチモジュール × Firebase Crashlytics
-
https://firebase.google.com/docs/ios/installation-methods?hl=ja#via-package-dot-swift ↩ ↩2
-
https://developer.apple.com/documentation/packagedescription/package/dependency/package(name:url:_:)-7zltl ↩
-
https://firebase.google.com/docs/crashlytics/ios/get-started?hl=ja ↩
-
https://firebase.google.com/docs/crashlytics/ios/get-started?hl=ja#set-up-dsym-uploading ↩
