App Center 崩溃 (tvOS)
每次应用崩溃时,App Center 崩溃都将自动生成崩溃日志。 日志首先写入设备的存储,当用户再次启动应用时,系统会将故障报告发送到 App Center。 对于 beta 版应用和活动应用(即提交到 App Store 的应用),收集崩溃都适用。 崩溃日志包含有价值的信息,可帮助您解决故障。
如果尚未在应用程序中设置 SDK,请按照 入门 部分进行操作。
此外,tvOS 上的崩溃日志需要带符号化,请查看说明如何为你的应用程序提供符号的 App Center 诊断文档 。
备注
若要接收正确的符号化堆栈跟踪,请确保已禁用 bitcode。 可以在 App Center 的 IOS 带符号化文档中了解有关 bitcode 的详细信息。
备注
在中 4.0.0 引入了 App Center 重大更改的版本。 按照 迁移到 APP CENTER SDK 4.0.0 和更高 版本,从以前的版本迁移 App Center。
生成测试崩溃
App Center 崩溃将为你提供一个 API,用于生成测试崩溃以便轻松测试 SDK。 此 API 只能在测试/测试版应用中使用,不会在生产应用中执行任何操作。
[MSACCrashes generateTestCrash];
Crashes.generateTestCrash()
获取有关以前的故障的详细信息
App Center 崩溃具有两个 Api,可提供有关应用崩溃情况的详细信息。
应用是否在上一个会话中收到内存不足警告?
在启动 SDK 之后的任何时候,你都可以在上一个会话中检查应用是否收到内存警告:
[MSACCrashes hasReceivedMemoryWarningInLastSession];
Crashes.hasReceivedMemoryWarningInLastSession
备注
此方法只能在启动后使用 Crashes ,它将始终返回 NO 或 false 在启动之前。
备注
在某些情况下,内存不足的设备不能发送事件。
应用在上一个会话中是否崩溃?
启动 SDK 之后,可以随时检查应用是否在上一次启动时崩溃:
[MSACCrashes hasCrashedInLastSession];
Crashes.hasCrashedInLastSession
如果你想要在发生崩溃后调整应用的行为或 UI,这会很方便。
备注
此方法只能在启动后使用 MSACCrashes ,它将始终返回 NO 或 false 在启动之前。
有关最后一个崩溃的详细信息
如果你的应用此前崩溃,你可以获取有关最后一个崩溃的详细信息。
MSACErrorReport *crashReport = [MSACCrashes lastSessionCrashReport];
var crashReport = Crashes.lastSessionCrashReport
备注
此方法只能在启动后使用 Crashes ,它将始终 nil 在开始之前返回。
此 API 有很多用例,最常见的用例是调用此 API 并实现其自定义 CrashesDelegate的人。
自定义 App Center 崩溃的使用情况
App Center 崩溃为开发人员提供回调,以便在向 App Center 发送崩溃日志之前和时执行其他操作。
若要添加自定义行为,需要采用 CrashesDelegate -协议,其所有方法都是可选的。
注册为委托
[MSACCrashes setDelegate:self];
Crashes.delegate = self
备注
您必须在调用 之前 设置委托 AppCenter.start ,因为 App Center 在启动后立即开始处理崩溃。
是否应处理崩溃?
crashes:shouldProcessErrorReport: CrashesDelegate 如果要确定是否需要处理特定的崩溃,请在类中实现-方法(采用-协议)。 例如,可能存在要忽略的系统级崩溃,并且不希望发送到 App Center。
- (BOOL)crashes:(MSACCrashes *)crashes shouldProcessErrorReport:(MSACErrorReport *)errorReport {
return YES; // return YES if the crash report should be processed, otherwise NO.
}
func crashes(_ crashes: Crashes, shouldProcess errorReport: ErrorReport) -> Bool {
return true; // return true if the crash report should be processed, otherwise false.
}
处理的错误
App Center 还允许通过使用处理的异常通过方法跟踪错误 trackError 。 应用可以选择将属性或/和附件附加到已处理的错误报告,以提供更多上下文。
@try {
// Throw error.
} @catch (NSError *error) {
// Init attachments.
NSArray<MSACErrorAttachmentLog *> attachments = @[ MSACErrorAttachmentLog attachmentWithText:@"Hello world!" filename:@"hello.txt"] ]
// Init properties.
NSDictionary *properties = @{ "Category" : "Music", "Wifi" : "On" };
// Track errors.
[MSACCrashes trackError:error withProperties:properties attachments:attachments];
[MSACCrashes trackError:error withProperties:properties attachments:nil];
[MSACCrashes trackError:error withProperties:nil attachments:attachments];
[MSACCrashes trackError:error withProperties:nil attachments:nil];
}
do {
// Throw error.
} catch {
// Init attachments.
let attachments = [ErrorAttachmentLog.attachment(withText: "Hello world!", filename: "hello.txt")]
// Init properties.
let properties:Dictionary<String, String> = ["Category" : "Music", "Wifi" : "On"]
// Track errors.
Crashes.trackError(error, properties: properties, attachments: attachments)
Crashes.trackError(error, properties: properties, attachments: nil)
Crashes.trackError(error, properties: nil, attachments: attachments)
Crashes.trackError(error, properties: nil, attachments: nil)
}
若要跟踪异常,可以使用 trackException 方法:
@try {
// Throw exceptions.
} @catch (NSException *exception) {
// Init exceptions.
MSACExceptionModel *customException1 = [MSACExceptionModel initWithType:@"Custom exception" exceptionMessage:"Track custom exception.", stackTrace:exception.callStackSymbols];
MSACExceptionModel *customException2 = [MSACExceptionModel initWithException:exception];
// Track exceptions.
[MSACCrashes trackException:customException1 withProperties:properties attachments:nil];
[MSACCrashes trackException:customException2 withProperties:properties attachments:nil];
}
do {
// Throw exception.
} catch {
// Init exception.
let exception = ExceptionModel(withType: "Custom exception", exceptionMessage: "Track custom exception.", stackTrace: Thread.callStackSymbols)
// Track exception.
Crashes.trackException(exception, properties: properties, attachments: nil)
}
要求用户同意发送崩溃日志
如果用户隐私对你很重要,你可能想要在将故障报告发送到 App Center 之前获得用户的确认。 SDK 公开了一个回调,该回调指示 App Center 崩溃,以便在发送任何崩溃报告之前等待用户确认。
如果你选择执行此操作,则需负责获取用户的确认,例如通过对话框提示获取以下选项之一: " 始终发送"、" 发送" 和 " 不发送"。 根据输入,将告知 App Center 崩溃要执行的操作,然后将相应地处理崩溃。
备注
SDK 不显示此对话框,应用必须提供自己的 UI 以请求用户同意。
备注
如果应用未实现用户确认对话框,则不应显式调用 ; notifyWithUserConfirmation 崩溃模块将处理隐式发送日志。
以下方法演示如何设置用户确认处理程序:
[MSACCrashes setUserConfirmationHandler:(^(NSArray<MSACErrorReport *> *errorReports) {
// Your code to present your UI to the user, e.g. an UIAlertController.
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:@"Sorry about that!"
message:@"Do you want to send an anonymous crash report so we can fix the issue?"
preferredStyle:UIAlertControllerStyleAlert];
[alertController
addAction:[UIAlertAction actionWithTitle:@"Don't send"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
[MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationDontSend];
}]];
[alertController
addAction:[UIAlertAction actionWithTitle:@"Send"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationSend];
}]];
[alertController
addAction:[UIAlertAction actionWithTitle:@"Always send"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationAlways];
}]];
// Show the alert controller.
[self.window.rootViewController presentViewController:alertController animated:YES completion:nil];
return YES; // Return YES if the SDK should await user confirmation, otherwise NO.
})];
MSACCrashes.setUserConfirmationHandler({ (errorReports: [MSACErrorReport]) in
// Your code to present your UI to the user, e.g. an UIAlertController.
let alertController = UIAlertController(title: "Sorry about that!",
message: "Do you want to send an anonymous crash report so we can fix the issue?",
preferredStyle:.alert)
alertController.addAction(UIAlertAction(title: "Don't send", style: .cancel) {_ in
MSACCrashes.notify(with: .dontSend)
})
alertController.addAction(UIAlertAction(title: "Send", style: .default) {_ in
MSACCrashes.notify(with: .send)
})
alertController.addAction(UIAlertAction(title: "Always send", style: .default) {_ in
MSACCrashes.notify(with: .always)
})
// Show the alert controller.
self.window?.rootViewController?.present(alertController, animated: true)
return true // Return true if the SDK should await user confirmation, otherwise return false.
})
如果返回上述处理程序块,应用应获取用户权限,并借助以下 API 向 SDK 发送消息 YES / true ,并返回结果。 如果使用警报,如上面的示例中所示,你将从 -callback 的实现中调用 alertView:clickedButtonAtIndex: 它。
// Depending on the users's choice, call notifyWithUserConfirmation: with the right value.
[MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationDontSend];
[MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationSend];
[MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationAlways];
// Depending on the user's choice, call notify(with:) with the right value.
MSACCrashes.notify(with: .dontSend)
MSACCrashes.notify(with: .send)
MSACCrashes.notify(with: .always)
获取有关故障日志发送状态的信息
有时,你想要了解应用崩溃的状态。 常见用例是,你可能想要显示 UI 来告知用户应用正在提交崩溃报告,或者,如果应用在启动后快速崩溃,则你需要调整应用的行为以确保可以提交崩溃日志。 -protocol 定义了三个不同的回调,可以在应用中使用这些回调来通知发生 CrashesDelegate 情况:
在 SDK 发送崩溃日志之前,将调用以下回调
- (void)crashes:(MSACCrashes *)crashes willSendErrorReport:(MSACErrorReport *)errorReport {
// Your code, e.g. to present a custom UI.
}
func crashes(_ crashes: Crashes, willSend errorReport: ErrorReport) {
// Your code, e.g. to present a custom UI.
}
如果终结点出现网络问题或中断,并且重启应用,则进程重启后会再次 willSendErrorReport 触发。
SDK 成功发送故障日志后,将调用以下回调
- (void)crashes:(MSACCrashes *)crashes didSucceedSendingErrorReport:(MSACErrorReport *)errorReport {
// Your code, e.g. to hide the custom UI.
}
func crashes(_ crashes: Crashes, didSucceedSending errorReport: ErrorReport) {
// Your code goes here.
}
如果 SDK 无法发送崩溃日志,将调用以下回调
- (void)crashes:(MSACCrashes *)crashes didFailSendingErrorReport:(MSACErrorReport *)errorReport withError:(NSError *)error {
// Your code goes here.
}
func crashes(_ crashes: Crashes, didFailSending errorReport: ErrorReport, withError error: Error) {
// Your code goes here.
}
接收 didFailSendingErrorReport 表示发生不可恢复的错误,如 4xx 代码。 例如 ,401 表示 appSecret 错误。
如果是网络问题,则不触发此回调。 在这种情况下,SDK 会不断重试 (,并且还会在网络连接关闭时暂停重试) 。
向崩溃报告添加附件
可以将二进制和文本附件添加到崩溃报告。 SDK 会随故障一起发送它们,以便可以在门户App Center它们。 在从以前的应用程序启动发送存储的崩溃之前,将调用以下回调。 崩溃时不会调用它。 以下示例演示了如何将文本和图像附加到崩溃:
- (NSArray<MSACErrorAttachmentLog *> *)attachmentsWithCrashes:(MSACCrashes *)crashes
forErrorReport:(MSACErrorReport *)errorReport {
MSACErrorAttachmentLog *attachment1 = [MSACErrorAttachmentLog attachmentWithText:@"Hello world!" filename:@"hello.txt"];
MSACErrorAttachmentLog *attachment2 = [MSACErrorAttachmentLog attachmentWithBinary:[@"Fake image" dataUsingEncoding:NSUTF8StringEncoding] filename:@"fake_image.jpeg" contentType:@"image/jpeg"];
return @[ attachment1, attachment2 ];
}
func attachments(with crashes: Crashes, for errorReport: ErrorReport) -> [ErrorAttachmentLog]? {
let attachment1 = ErrorAttachmentLog.attachment(withText: "Hello world!", filename: "hello.txt")
let attachment2 = ErrorAttachmentLog.attachment(withBinary: "Fake image".data(using: String.Encoding.utf8), filename: nil, contentType: "image/jpeg")
return [attachment1!, attachment2!]
}
备注
大小限制当前为 7 MB。 尝试发送更大的附件将触发错误。
启用或禁用App Center崩溃
可以在运行时启用和App Center崩溃。 如果禁用它,SDK 将不会对应用执行任何崩溃报告。
[MSACCrashes setEnabled:NO];
Crashes.enabled = false
若要再次App Center崩溃,请使用同一 API,但作为 YES / true 参数传递。
[MSACCrashes setEnabled:YES];
Crashes.enabled = true
状态在应用程序启动时一直保留于设备的存储中。
备注
此方法只能在启动后 Crashes 使用。
检查App Center崩溃是否已启用
还可以检查是否App Center崩溃:
BOOL enabled = [MSACCrashes isEnabled];
var enabled = Crashes.enabled
备注
此方法只能在启动后 Crashes 使用,它始终在启动 false 之前返回。