App Center Crashes

App Center Crashes will automatically generate a crash log every time your app crashes. The log is first written to the device's storage and when the user starts the app again, the crash report will be sent to App Center. Collecting crashes works for both beta and live apps, i.e. those submitted to the App Store. Crash logs contain valuable information for you to help fix the crash.

Follow the Getting Started section if you haven't set up the SDK in your application yet.

Also note that crash logs on iOS require Symbolication, check out the App Center Diagnostics documentation that explains how to provide symbols for your app.

Note

The SDK will not forward any crash log if you are attached to the debugger. Make sure the debugger is not attached when you crash the app.

Note

To receive properly symbolicated stack traces, please ensure bitcode is disabled. You can learn more about bitcode in App Center's iOS Symbolication documentation.

Generate a test crash

App Center Crashes provides you with an API to generate a test crash for easy testing of the SDK. This API can only be used in test/beta apps and won't do anything in production apps.

[MSCrashes generateTestCrash];
MSCrashes.generateTestCrash()

Get more information about a previous crash

App Center Crashes has two APIs that give you more information in case your app has crashed.

Did the app receive a low memory warning in the previous session?

At any time after starting the SDK, you can check if the app received a memory warning in the previous session:

[MSCrashes hasReceivedMemoryWarningInLastSession];
MSCrashes.hasReceivedMemoryWarningInLastSession()

Note

This method must only be used after MSCrashes has been started, it will always return NO or false before start.

Note

In some cases, a device with low memory may not be able to send events.

Did the app crash in the previous session?

At any time after starting the SDK, you can check if the app crashed in the previous launch:

[MSCrashes hasCrashedInLastSession];
MSCrashes.hasCrashedInLastSession()

This comes in handy in case you want to adjust the behavior or UI of your app after a crash has occurred.

Note

This method must only be used after MSCrashes has been started, it will always return NO or false before start.

Details about the last crash

If your app crashed previously, you can get details about the last crash.

MSErrorReport *crashReport = [MSCrashes lastSessionCrashReport];
var crashReport = MSCrashes.lastSessionCrashReport()

Note

This method must only be used after MSCrashes has been started, it will always return nil before start.

There are numerous use cases for this API, the most common one is people who call this API and implement their custom MSCrashesDelegate.

Customize your usage of App Center Crashes

App Center Crashes provides callbacks for developers to perform additional actions before and when sending crash logs to App Center.

To add your custom behavior, you need to adopt the MSCrashesDelegate-protocol, all of its methods are optional.

Register as a delegate

[MSCrashes setDelegate:self];
MSCrashes.setDelegate(self)

Note

You must set the delegate before calling [MSAppCenter start], since App Center starts processing crashes immediately after the start.

Should the crash be processed?

Implement the crashes:shouldProcessErrorReport:-method in the class that adopts the MSCrashesDelegate-protocol if you'd like to decide if a particular crash needs to be processed or not. For example, there could be a system level crash that you'd want to ignore and that you don't want to send to App Center.

- (BOOL)crashes:(MSCrashes *)crashes shouldProcessErrorReport:(MSErrorReport *)errorReport {
  return YES; // return YES if the crash report should be processed, otherwise NO.
}
func crashes(_ crashes: MSCrashes!, shouldProcessErrorReport errorReport: MSErrorReport!) -> Bool {
  return true; // return true if the crash report should be processed, otherwise false.
}

If user privacy is important to you, you might want to get user confirmation before sending a crash report to App Center. The SDK exposes a callback that tells App Center Crashes to await user confirmation before sending any crash reports.

If you chose to do so, you are responsible for obtaining the user's confirmation, for example, through a dialog prompt with one of the following options: Always send, Send, and Don't send. Based on the input, you will tell App Center Crashes what to do and the crash will then be handled accordingly.

Note

The SDK does not display a dialog for this, the app must provide its own UI to ask for user consent.

Note

The app should not call notifyWithUserConfirmation explicitly if it does not implement a user confirmation dialog; the Crashes module will handle sending logs for you implicitly.

The following method shows how to set up a user confirmation handler:

[MSCrashes setUserConfirmationHandler:(^(NSArray<MSErrorReport *> *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) {
                                        [MSCrashes notifyWithUserConfirmation:MSUserConfirmationDontSend];
                                      }]];

  [alertController
      addAction:[UIAlertAction actionWithTitle:@"Send"
                                        style:UIAlertActionStyleDefault
                                      handler:^(UIAlertAction *action) {
                                        [MSCrashes notifyWithUserConfirmation:MSUserConfirmationSend];
                                      }]];

  [alertController
      addAction:[UIAlertAction actionWithTitle:@"Always send"
                                        style:UIAlertActionStyleDefault
                                      handler:^(UIAlertAction *action) {
                                        [MSCrashes notifyWithUserConfirmation:MSUserConfirmationAlways];
                                      }]];
  // 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.
})];
MSCrashes.setUserConfirmationHandler({ (errorReports: [MSErrorReport]) 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
    MSCrashes.notify(with: .dontSend)
  })

  alertController.addAction(UIAlertAction(title: "Send", style: .default) {_ in
    MSCrashes.notify(with: .send)
  })

  alertController.addAction(UIAlertAction(title: "Always send", style: .default) {_ in
    MSCrashes.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.
})

In case you return YES/true in the handler block above, your app should obtain user permission and message the SDK with the result using the following API. If you are using an alert for this, as we do in the sample above, you would call it from within your implementation of the alertView:clickedButtonAtIndex:-callback.

// Depending on the users's choice, call notifyWithUserConfirmation: with the right value.
[MSCrashes notifyWithUserConfirmation:MSUserConfirmationDontSend];
[MSCrashes notifyWithUserConfirmation:MSUserConfirmationSend];
[MSCrashes notifyWithUserConfirmation:MSUserConfirmationAlways];
// Depending on the user's choice, call notify(with:) with the right value.
MSCrashes.notify(with: .dontSend)
MSCrashes.notify(with: .send)
MSCrashes.notify(with: .always)

Get information about the sending status for a crash log

At times, you would like to know the status of your app crash. A common use case is that you might want to show UI that tells the users that your app is submitting a crash report, or, in case your app is crashing very quickly after the launch, you want to adjust the behavior of the app to make sure the crash logs can be submitted. The MSCrashesDelegate-protocol defines three different callbacks that you can use in your app to be notified of what is going on:

The following callback will be invoked before the SDK sends a crash log

- (void)crashes:(MSCrashes *)crashes willSendErrorReport:(MSErrorReport *)errorReport {
  // Your code, e.g. to present a custom UI.
}
func crashes(_ crashes: MSCrashes!, willSend errorReport: MSErrorReport!) {
  // Your code, e.g. to present a custom UI.
}

The following callback will be invoked after the SDK sent a crash log successfully

- (void)crashes:(MSCrashes *)crashes didSucceedSendingErrorReport:(MSErrorReport *)errorReport {
  // Your code, e.g. to hide the custom UI.
}
func crashes(_ crashes: MSCrashes!, didSucceedSending errorReport: MSErrorReport!) {
  // Your code goes here.
}

The following callback will be invoked if the SDK failed to send a crash log

- (void)crashes:(MSCrashes *)crashes didFailSendingErrorReport:(MSErrorReport *)errorReport withError:(NSError *)error {
  // Your code goes here.
}
func crashes(_ crashes: MSCrashes!, didFailSending errorReport: MSErrorReport!, withError error: Error!) {
  // Your code goes here.
}

Add attachments to a crash report

You can add one binary and one text attachment to a crash report. The SDK will send it along with the crash so that you can see it in App Center portal. The following callback will be invoked right before sending the stored crash from previous application launches. It will not be invoked when the crash happens. Here is an example of how to attach text and an image to a crash:

- (NSArray<MSErrorAttachmentLog *> *)attachmentsWithCrashes:(MSCrashes *)crashes
                                             forErrorReport:(MSErrorReport *)errorReport {
  MSErrorAttachmentLog *attachment1 = [MSErrorAttachmentLog attachmentWithText:@"Hello world!" filename:@"hello.txt"];
  MSErrorAttachmentLog *attachment2 = [MSErrorAttachmentLog attachmentWithBinary:[@"Fake image" dataUsingEncoding:NSUTF8StringEncoding] filename:@"fake_image.jpeg" contentType:@"image/jpeg"];
  return @[ attachment1, attachment2 ];
}
func attachments(with crashes: MSCrashes, for errorReport: MSErrorReport) -> [MSErrorAttachmentLog] {
  let attachment1 = MSErrorAttachmentLog.attachment(withText: "Hello world!", filename: "hello.txt")
  let attachment2 = MSErrorAttachmentLog.attachment(withBinary: "Fake image".data(using: String.Encoding.utf8), filename: nil, contentType: "image/jpeg")
  return [attachment1!, attachment2!]
}

Note

The size limit is currently 7 MB. Attempting to send a larger attachment will trigger an error.

Enable or disable App Center Crashes at runtime

You can enable and disable App Center Crashes at runtime. If you disable it, the SDK will not do any crash reporting for the app.

[MSCrashes setEnabled:NO];
MSCrashes.setEnabled(false)

To enable App Center Crashes again, use the same API but pass YES/true as a parameter.

[MSCrashes setEnabled:YES];
MSCrashes.setEnabled(true)

The state is persisted in the device's storage across application launches.

Note

This method must only be used after Crashes has been started.

Check if App Center Crashes is enabled

You can also check if App Center Crashes is enabled or not:

BOOL enabled = [MSCrashes isEnabled];
var enabled = MSCrashes.isEnabled()

Note

This method must only be used after Crashes has been started, it will always return false before start.

Disabling Mach exception handling

By default, App Center Crashes uses the Mach exception handler to catch fatal signals, e.g. stack overflows, via a Mach exception server.

The disableMachExceptionHandler-method provides an option to disable catching fatal signals via a Mach exception server. If you want to disable the Mach exception handler, you should call this method BEFORE starting the SDK. Your typical setup code would look like this:

[MSCrashes disableMachExceptionHandler];
[MSAppCenter start:@"{Your App Secret}" withServices:@[[MSAnalytics class], [MSCrashes class]]];
MSCrashes.disableMachExceptionHandler()
MSAppCenter.start("{Your App Secret}", withServices: [MSAnalytics.self, MSCrashes.self])