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 ,它将始终返回 NOfalse 在启动之前。

备注

在某些情况下,内存不足的设备不能发送事件。

应用在上一个会话中是否崩溃?

启动 SDK 之后,可以随时检查应用是否在上一次启动时崩溃:

[MSACCrashes hasCrashedInLastSession];
Crashes.hasCrashedInLastSession

如果你想要在发生崩溃后调整应用的行为或 UI,这会很方便。

备注

此方法只能在启动后使用 MSACCrashes ,它将始终返回 NOfalse 在启动之前。

有关最后一个崩溃的详细信息

如果你的应用此前崩溃,你可以获取有关最后一个崩溃的详细信息。

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 之前返回。