现在,您可以使用全新官方 Firebase Crashlytics SDK 在应用中设置 Crashlytics,该 SDK 提供了与其他 Firebase 产品更为一致、更加直观易用的改进版 API。
本指南介绍了如何从旧版 Fabric SDK 升级为新 SDK。其中说明了新 API 中的更改、更改的原因,以及如何更新代码(如果需要)。
准备工作
第 1 步:添加 Firebase 配置文件
打开您的项目设置。在您的应用卡片中,选择您需要为其添加配置文件的应用的软件包 ID。
点击下载 GoogleService-Info.plist,获取 Firebase Apple 平台配置文件 (
GoogleService-Info.plist
)。您可以随时再次下载 Firebase Apple 平台配置文件。
请确保该配置文件名未附加其他字符,如
(2)
。
将配置文件移至 Xcode 项目的根目录中。如果出现提示,请选择将配置文件添加到所有目标。
如果您的项目中有多个软件包 ID,则必须将每个软件包 ID 与 Firebase 控制台中的注册应用相关联,使每个应用都有自己的 GoogleService-Info.plist
文件。
第 2 步:添加 Firebase Crashlytics SDK
在 CocoaPods 内的所有目标中,将
Fabric
和Crashlytics
Pod 替换为Firebase/Crashlytics
Pod。# Add the pod for Firebase Crashlytics pod 'Firebase/Crashlytics'
# Recommended: Add the Firebase pod for Google Analytics pod 'Firebase/Analytics'直接从 Fabric 中卸载或移除第三方依赖项,例如 Fabric Answers 和第三方套件的依赖项。
安装并更新 Pod,然后打开
.xcworkspace
文件以便在 Xcode 中查看项目:pod install
open YOUR_PROJECT.xcworkspace
第 3 步:更新您的代码
在 Xcode 中,重建您的应用,然后再次打开 .xcworkspace 文件。
查看以下 SDK 更改,并对您的代码进行适当的更新:
Crashlytics 现在会根据 Firebase 安装 ID 轮替 ID。
Crashlytics 使用 Crashlytics 安装 UUID 来标识应用的实例,并将用户数据与其设备相关联。 以前,Crashlytics 会在设备的广告 ID 发生更改时轮替用户的安装 UUID。现在,Crashlytics 会根据用户的 Firebase 安装 ID (FID) 来轮替安装 UUID。如需了解详情,请访问管理 Firebase 安装 ID。
更改的原因
使用 FID,以便与其他 Firebase SDK 保持一致。
run 脚本和 upload-symbols 脚本现位于 FirebaseCrashlytics 中。
您现在可以从新的 FirebaseCrashlytics
库访问 run
和 upload-symbols
脚本。请注意,您仍然可以在构建流程中随时调用 upload-symbols
,以便手动上传 dSYM。
此外,新 SDK 中已不再包含 Fabric 的 API_KEY 和 BUILD_SECRET。Crashlytics 现在会使用您的应用的 GoogleService-info.plist
,以将应用与您的 Firebase 项目相关联,并保留历史崩溃数据。
Fabric SDK
${PODS_ROOT}/Fabric/run API_KEY BUILD_SECRET /path/to/pods/directory/Fabric/upload-symbols
Firebase Crashlytics SDK
${PODS_ROOT}/FirebaseCrashlytics/run /path/to/pods/directory/FirebaseCrashlytics/upload-symbols
更改的原因
Crashlytics 已不再将 Fabric SDK 用作依赖项,因此我们将 CLI 工具移到了新的库中。
Crashlytics 库现在名为 FirebaseCrashlytics。
在应用中,更新导入路径如下:
Fabric SDK
Swift
import Crashlytics
Objective-C
@import Crashlytics
Firebase Crashlytics SDK
Swift
import FirebaseCrashlytics
Objective-C
@import FirebaseCrashlytics
更改的原因
更新 Crashlytics
库的名称,以使其与其他 Firebase 库保持一致(例如,FirebaseFirestore
和 FirebaseAuth
)。
FirebaseCrashlytics 不再支持 Fabric SDK。
现在,FirebaseCrashlytics
只能通过 Firebase Crashlytics SDK 进行初始化。您可以通过在 Swift 中调用 FirebaseApp.configure
或在 Objective-C 中调用 [FIRApp configure]
来启动 FirebaseCrashlytics
实例。
在 application:didFinishLaunchingWithOptions
中,将对 Fabric.with
和 startWithAPIKey
的调用替换为对 FirebaseApp
的调用:
Fabric SDK
Swift
Fabric.with([Crashlytics.self])
Objective-C
[Fabric with:@[[Crashlytics class]]];
+ startWithAPIKey:
+ startWithAPIKey:delegate:
Firebase Crashlytics SDK
Swift
FirebaseApp.configure()
Objective-C
[FIRApp configure];
更改的原因
使用新方法初始化 Crashlytics 与其他 Firebase 服务的初始化方式更加一致。
crash 和 throwException 方法已移除。
新 SDK 不再包含 crash
或 throwException
方法,而是改为使用 fatalError
(在 Swift 中)或空数组(在 Objective-C 中)强制造成崩溃。
Firebase Crashlytics SDK
Swift
// Force a test crash
fatalError()
Objective-C
// Force a test crash
@[][1];
更改的原因
多种不同的原因可能造成多种不同类型的崩溃,这些方法并未明确指出最终崩溃是在运行时还是应用的原生 SDK 中发生。
sharedInstance 方法现已更名为 crashlytics。
新 SDK 不再包含 sharedInstance
方法。
如需初始化 Crashlytics,请改为使用 crashlytics
(如需了解详情,请参阅 Swift 或 Objective-C 参考文档)。在您的应用委托中,以如下方式更新初始化脚本:
Fabric SDK
Swift
Crashlytics.sharedInstance()
Objective-C
[Crashlytics sharedInstance];
Firebase Crashlytics SDK
Swift
Crashlytics.crashlytics()
Objective-C
[FIRCrashlytics crashlytics];
更改的原因
我们已对实例 getter 方法进行了重命名,以便与其他 Firebase SDK 保持一致。
setUserIdentifier 现已更改为 setUserID。setUserName 和 setUserEmail 已移除。
以前,您可以使用 setUserName
和 setUserEmail
设置与崩溃相关联的名称或电子邮件地址,但现在已经不再定义这些方法。如需为用户设置 ID,新的首选方法是使用 setUserID
。
Fabric SDK
Swift
Crashlytics.sharedInstance().setUserIdentifier("user_id")
Crashlytics.sharedInstance().setUserEmail("user_email")
Crashlytics.sharedInstance().setUserName("user_name")
Objective-C
[[Crashlytics sharedInstance] setUserIdentifier:@"user_id"];
[[Crashlytics sharedInstance] setUserEmail:@"user_email"];
[[Crashlytics sharedInstance] setUserName:@"user_name"];
Firebase Crashlytics SDK
Swift
Crashlytics.crashlytics().setUserID("user_id")
Objective-C
[[FIRCrashlytics crashlytics] setUserID:@"user_id"];
更改的原因
我们采用了方法名称 setUserID
以便与其他 Firebase API 保持一致,此外由于不建议通过 Crashlytics 记录个人身份信息 (PII),我们移除了 setUserName
和 setUserEmail
。
CLSLogv 和 CLSNSLogv 已被日志记录函数所取代。
新 SDK 不再包含 CLSLogv
或 CLSNSLogv
函数。如需添加自定义日志消息,请使用 Crashlytics
库中的新日志记录方法。
请注意,新方法不再输出到 stdout
或 NSLog
(如果您希望保留此行为,建议您编写封装容器)。
Fabric SDK
Swift
CLSLogv("%@, %@", getVaList([first_arg, second_arg]))
CLSNSLogv("%@, %@", getVaList([first_arg, second_arg]))
Objective-C
CLSLog(@"%@, %@", first_arg, second_arg);
CLSNSLog(@"%@, %@", first_arg, second_arg);
CLSLogv(@"%@, %@", args_va_list);
CLSNSLogv(@"%@, %@", args_va_list);
CLS_LOG(@"%@, %@", first_arg, second_arg);
Firebase Crashlytics SDK
Swift
Crashlytics.crashlytics().log("\(first_arg), \(second_arg)")
Crashlytics.crashlytics().log(format: "%@, %@", arguments: getVaList([first_arg, second_arg]))
Objective-C
[[FIRCrashlytics crashlytics] log:@"first_arg, second_arg"];
[[FIRCrashlytics crashlytics] logWithFormat:@"%@, %@", first_arg, second_arg];
如果您使用了 CLS_LOG
,请将以下内容添加到头文件中,以继续在日志语句中获取文件名和行号:
#define CLS_LOG(__FORMAT__, ...) [[FIRCrashlytics crashlytics] logWithFormat:@"%s line %d $ " __FORMAT__, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__]
更改的原因
新方法需要实例,这让您可以更轻松地测试代码。
setCustomValue 将取代 setObjectValue、setIntValue、setFloatValue 和 setBoolValue。
新 SDK 中已不再包含自定义 setter 方法。
以前,您可以使用这些方法来设置键值对,以便随崩溃报告一起发送。现在,您可以使用 setCustomValue:forKey
为所有数据类型设置键值对。
Fabric SDK
Swift
Crashlytics.sharedInstance().setObjectValue("value", forKey: "object_key")
Crashlytics.sharedInstance().setIntValue(100, forKey: "int_key")
Crashlytics.sharedInstance().setFloatValue(99.9, forKey: "float_key")
Crashlytics.sharedInstance().setBoolValue(true, forKey: "bool_key")
Objective-C
[[Crashlytics sharedInstance] setObjectValue:@"key" forKey:@"object_key"];
[[Crashlytics sharedInstance] setIntValue:100 forKey:@"int_key"];
[[Crashlytics sharedInstance] setFloatValue:99.9 forKey:@"float_key"];
[[Crashlytics sharedInstance] setBoolValue:YES forKey:@"bool_key"];
Firebase Crashlytics SDK
Swift
Crashlytics.crashlytics().setCustomValue("value", forKey: "object_key")
Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key")
Crashlytics.crashlytics().setCustomValue(99.9, forKey: "float_key")
Crashlytics.crashlytics().setCustomValue(true, forKey: "bool_key")
Objective-C
[[FIRCrashlytics crashlytics] setCustomValue:@"value" forKey:@"object_key"];
[[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"];
[[FIRCrashlytics crashlytics] setCustomValue:@(99.9) forKey:@"float_key"];
[[FIRCrashlytics crashlytics] setCustomValue:@YES forKey:@"bool_key"];
更改的原因
新方法名称是 Crashlytics 所独有的,明示了 Crashlytics 不符合键值对格式。
recordCustomExceptionName:reason:frameArray: 已被 Exception Model API 所取代。
如果您的应用在非原生环境(例如,JavaScript 或 Unity)中运行,则可以使用 Exception Model API 以应用的原生异常格式报告崩溃元数据。
Fabric SDK
Swift
let topFrame = CLSStackFrame() topFrame.symbol = "doSomethingBad" topFrame.fileName = "bad.cc" topFrame.lineNumber = 23
let middleFrame = CLSStackFrame()
middleFrame.symbol = "doOtherStuff"
middleFrame.fileName = "stuff.cc"
middleFrame.lineNumber = 23;
let bottomFrame = CLSStackFrame()
bottomFrame.symbol = "main"
bottomFrame.fileName = "main.cc"
bottomFrame.lineNumber = 123
Crashlytics.sharedInstance().recordCustomExceptionName("FooException",
reason: "There was a foo.",
frameArray: [topFrame, middleFrame, bottomFrame])
Objective-C
CLSStackFrame *topFrame = [[CLSStackFrame alloc] init];
topFrame.symbol = @"doSomethingBad";
topFrame.fileName = @"bad.cc";
topFrame.lineNumber = 23;
CLSStackFrame *middleFrame = [[CLSStackFrame alloc] init];
middleFrame.symbol = @"doOtherStuff";
middleFrame.fileName = @"stuff.cc";
middleFrame.lineNumber = 23;
CLSStackFrame *bottomFrame = [[CLSStackFrame alloc] init];
bottomFrame.symbol = @"main";
bottomFrame.fileName = @"main.cc";
bottomFrame.lineNumber = 123;
[[Crashlytics sharedInstance] recordCustomExceptionName:@"FooException"
reason:@"There was a foo."
frameArray:@[topFrame, middleFrame, bottomFrame]];
Firebase Crashlytics SDK
Swift
var ex = ExceptionModel.init(name:"FooException", reason:"There was a foo.")
ex.stackTrace = [
StackFrame.init(symbol:"makeError" fileName:"handler.js" lineNumber:495),
StackFrame.init(symbol:"then" fileName:"routes.js" lineNumber:102),
StackFrame.init(symbol:"main" fileName:"app.js" lineNumber:12),
]
crashlytics.record(exceptionModel:ex)
Objective-C
model.stackTrace = @[
[FIRStackFrame stackFrameWithSymbol:@"makeError" fileName:@"handler.js" lineNumber:495],
[FIRStackFrame stackFrameWithSymbol:@"then" fileName:@"routes.js" lineNumber:102],
[FIRStackFrame stackFrameWithSymbol:@"main" fileName:@"app.js" lineNumber:12],
];
更改的原因
这是用户很久以来一直都希望我们提供的一项功能,让您可以将 Crashlytics 扩展到其他平台(如 Unity、Flutter 或 React Native)。
CrashlyticsDelegate 已被多个处理崩溃报告的方法所取代。
您现在可以使用一组新的方法来处理崩溃报告:
didFinishLaunchingWithOptions
现已被新的处理程序checkForUnsentReportsWithCompletion
所取代。crashlyticsDidDetectReportForLastExecution
现已被didCrashDuringPreviousExecution
所取代。didCrashDuringPreviousExecution
可让您方便地检测在上次运行应用期间发生的崩溃。crashlyticsCanUseBackgroundSessions
现已永久设置为 true。我们不再支持在委托中检查
CLSReport
对象。
默认情况下,Crashlytics 会在启动时自动上传崩溃报告,而在先前的版本中,您可以调用 didFinishLaunchingWithOptions
,让用户自选启用崩溃报告。
现在,当您调用 setCrashlyticsCollectionEnabled=false
关闭自动崩溃报告时,Crashlytics 会调用 checkForUnsentReportsWithCompletion
,这样您的用户就可以选择是否在您的应用崩溃时发送崩溃报告。然后,您可以在用户选择启用时调用 sendUnsentReports
,或者在用户选择退出时调用 deleteUnsentReports
。
请注意,您还可以在 checkForUnsentReportsWithCompletion
之外调用 sendUnsentReports
和 deleteUnsentReports
。例如,如果您的用户已通过一揽子批准或一揽子拒批的方式允许或禁止您发送崩溃报告,那么您可能想要永久设置或停用崩溃报告。请记住,如果您的应用在其生命周期的早期阶段崩溃,您可能永远不会收到崩溃报告。
Fabric SDK
Swift
class YourClassName: CrashlyticsDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions
...
Crashlytics.sharedInstance().delegate = self
...
return true
}
func crashlyticsDidDetectReport(forLastExecution report: CLSReport, completionHandler: @escaping (Bool) -> Void) {
/* ... handle unsent reports */
}
func crashlyticsCanUseBackgroundSessions(_ crashlytics: Crashlytics) -> Bool {
return true
}
}
Objective-C
@interface YourClassName <CrashlyticsDelegate> ()
@end
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
[[Crashlytics sharedInstance] setDelegate:self];
...
return YES;
}
-(void)crashlyticsDidDetectReportForLastExecution:(CLSReport *)report completionHandler:(void (^)(BOOL submit))completionHandler {
// ... handle unsent reports
}
-(BOOL)crashlyticsCanUseBackgroundSessions:(Crashlytics *)crashlytics {
return YES;
}
@end
Firebase Crashlytics SDK
Swift
/* You must set setCrashlyticsCollectionEnabled to false in order to use
checkForUnsentReportsWithCompletion. */
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(false)
Crashlytics.crashlytics().checkForUnsentReports { hasUnsentReport in
let hasUserConsent = false
// ...get user consent.
if hasUserConsent && hasUnsentReport {
Crashlytics.crashlytics().sendUnsentReports()
} else {
Crashlytics.crashlytics().deleteUnsentReports()
}
}
// Detect when a crash happens during your app's last run.
if Crashlytics.crashlytics().didCrashDuringPreviousExecution() {
// ...notify the user.
}
Objective-C
/* You must set setCrashlyticsCollectionEnabled to false in order to use
checkForUnsentReportsWithCompletion. */
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:false];
[[FIRCrashlytics crashlytics] checkForUnsentReportsWithCompletion:^(BOOL hasUnsentReports) {
BOOL hasConsent = false;
// ...get consent from user.
if (hasConsent && hasUnsentReports) {
[[FIRCrashlytics crashlytics] sendUnsentReports];
} else {
[[FIRCrashlytics crashlytics] deleteUnsentReports];
}
}];
// Detect when a crash happens during your app's last run.
if ([[FIRCrashlytics crashlytics] didCrashDuringPreviousExecution]) {
// ...notify the user.
}
更改的原因
该组新方法让您可以更好地控制应用的崩溃报告行为。 此外,在初始化 Crashlytics 之前,您不再需要设置 CrashlyticsDelegate。
firebase_crashlytics_collection_enabled 已被 FirebaseCrashlyticsCollectionEnabled 所取代。
当您在 Info.plist
中将 FirebaseCrashlyticsCollectionEnabled
设置为 false 时,Crashlytics 会在启动时停止自动发送崩溃报告。首次运行应用后,您还可以通过在 Crashlytics.h
中将 setCrashlyticsCollectionEnabled
设置为 false
来停用崩溃报告,但请注意,setCrashlyticsCollectionEnabled
会替换此标志。
替换 Info.plist
中的 firebase_crashlytics_collection_enabled
键以关闭自动收集功能:
键:
FirebaseCrashlyticsCollectionEnabled
值:
false
首次运行应用后,您还可以将以下代码添加到 Crashlytics.h
来关闭自动收集功能:
Firebase Crashlytics SDK
Swift
// setCrashlyticsCollectionEnabled is set to true by default.
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(false)
Objective-C
// setCrashlyticsCollectionEnabled is set to true by default.
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:false];
更改的原因
现在,在停用自动崩溃报告时,您可以更好地控制 Crashlytics 如何处理尚未发送的崩溃报告。将 FirebaseCrashlyticsCollectionEnabled
设置为 false 后,您可以从应用的任何位置调用 checkForUnsentReportsWithCompletion
,并根据用户的选择发送或删除尚未发送的报告。
现在,Crashlytics 始终使用后台会话。
以前,如果您不想在应用中支持后台会话,可以将 crashlyticsCanUseBackgroundSessions
设置为 false。
现在,crashlyticsCanUseBackgroundSessions
始终设置为 true。
更改的原因
我们不再支持低于 7.0 的 iOS 版本和低于 OS X 10.9 的 macOS 版本,这些版本均不支持后台会话。
Crashlytics 只能使用 Google Analytics(分析)收集的数据。
升级到 Firebase Crashlytics SDK 后,您将无法再通过 Fabric Answers 收集数据。如需获取“未受崩溃事件影响的用户数”指标和面包屑导航,请改为使用 Google Analytics(分析)。请注意,您的 Answers 历史解答数据无法迁移到 Firebase。
访问开始使用 Google Analytics(分析),以了解如何将 Google Analytics(分析)添加到您的应用中。
更改的原因
我们现在提供 Google Analytics(分析),以帮助您更深入地了解崩溃数据。借助 Analytics(分析),您可以继续在 Firebase 控制台中收集应用的统计信息。
后续步骤
强制造成一次测试崩溃,以将崩溃报告发送到 Firebase 控制台中的 Crashlytics 信息中心,从而测试您的实现。
您可以通过添加自选式报告、日志、键以及跟踪非严重错误来自定义崩溃报告设置。
将 Google Analytics(分析)添加到您的应用。将 Google Analytics(分析)的强大功能与 Firebase Crashlytics 结合使用,在 Firebase 控制台中查看关于未遇到崩溃问题的用户的统计信息。