Freigeben über


App Center-Abstürze (macOS)

Von Bedeutung

Visual Studio App Center wurde am 31. März 2025 eingestellt, mit Ausnahme der Analyse- und Diagnosefeatures, die bis zum 30. Juni 2026 weiterhin unterstützt werden. Weitere Informationen

App Center-Abstürze generieren automatisch ein Absturzprotokoll jedes Mal, wenn Ihre App abstürzt. Das Protokoll wird zuerst in den Speicher des Geräts geschrieben und wenn der Benutzer die App erneut startet, wird der Absturzbericht an das App Center gesendet. Das Sammeln von Abstürze funktioniert sowohl für Beta- als auch für Live-Apps, d. h. für an den App Store übermittelte Apps. Absturzprotokolle enthalten wertvolle Informationen für Sie, um den Absturz zu beheben.

Folgen Sie dem Abschnitt " Erste Schritte ", wenn Sie das SDK noch nicht in Ihrer Anwendung eingerichtet haben.

Außerdem benötigen Absturzprotokolle unter macOS eine Symbolisierung. Lesen Sie die App Center-Diagnosedokumentation, in der erklärt wird, wie Sie Symbole für Ihre App bereitstellen.

Hinweis

In der 4.0.0 Version des App Center wurden bahnbrechende Änderungen eingeführt. Folgen Sie dem Abschnitt "Migrieren zu App Center SDK 4.0.0" und höher , um App Center aus früheren Versionen zu migrieren.

Berichterstattung über Abstürze in Erweiterungen

App Center unterstützt Absturzberichte in macOS-Erweiterungen. Die Verwendung ist identisch mit der Containeranwendung.

Generieren eines Testabsturzes

App Center Crashes bietet Ihnen eine API zum Generieren eines Testabsturzes für einfache Tests des SDK. Diese API kann nur in Test-/Beta-Apps verwendet werden und führt in Produktions-Apps nichts aus.

[MSACCrashes generateTestCrash];
Crashes.generateTestCrash()

Abrufen weiterer Informationen zu einem vorherigen Absturz

App Center Crashes bietet zwei APIs, mit denen Sie weitere Informationen erhalten, falls Ihre App abgestürzt ist.

Hat die App in der vorherigen Sitzung eine Warnung mit geringem Arbeitsspeicher erhalten?

Nach dem Starten des SDK können Sie jederzeit überprüfen, ob die App in der vorherigen Sitzung eine Speicherwarnung erhalten hat:

[MSACCrashes hasReceivedMemoryWarningInLastSession];
Crashes.hasReceivedMemoryWarningInLastSession

Hinweis

Diese Methode darf nur verwendet werden, nachdem Crashes sie gestartet wurde, sie wird immer zurückgegeben NO oder false vor dem Start.

Hinweis

In einigen Fällen kann ein Gerät mit geringem Arbeitsspeicher keine Ereignisse senden.

Stürzte die App in der vorherigen Sitzung ab?

Nach dem Starten des SDK können Sie jederzeit überprüfen, ob die App beim vorherigen Start abgestürzt ist:

[MSACCrashes hasCrashedInLastSession];
Crashes.hasCrashedInLastSession

Dies ist praktisch, wenn Sie das Verhalten oder die Benutzeroberfläche Ihrer App nach dem Absturz anpassen möchten.

Hinweis

Diese Methode darf nur verwendet werden, nachdem MSACCrashes sie gestartet wurde, sie wird immer zurückgegeben NO oder false vor dem Start.

Details zum letzten Absturz

Wenn Ihre App zuvor abgestürzt ist, können Sie Details zum letzten Absturz abrufen.

MSACErrorReport *crashReport = [MSACCrashes lastSessionCrashReport];
var crashReport = Crashes.lastSessionCrashReport

Hinweis

Diese Methode darf nur verwendet werden, nachdem Crashes gestartet wurde; vor dem Start wird aber immer nil zurückgegeben.

Es gibt zahlreiche Anwendungsfälle für diese API. Der häufigste sind Personen, die diese API aufrufen und ihre benutzerdefinierte CrashesDelegate implementieren.

Passen Sie die Nutzung von App Center Crashes an.

App Center-Abstürze bieten Entwicklern Rückrufe, um zusätzliche Aktionen vor und beim Senden von Absturzprotokollen an App Center auszuführen.

Um Ihr benutzerdefiniertes Verhalten hinzuzufügen, müssen Sie das CrashesDelegate-Protokoll übernehmen, alle zugehörigen Methoden sind optional.

Registrieren als Stellvertretung

[MSACCrashes setDelegate:self];
Crashes.delegate = self

Hinweis

Sie müssen die Stellvertretung vor dem Aufrufen AppCenter.startfestlegen, da die Verarbeitung von App Center unmittelbar nach dem Start abstürzt.

Sollte der Absturz verarbeitet werden?

Implementieren Sie die crashes:shouldProcessErrorReport:-Methode in der Klasse, die das CrashesDelegate-Protokoll verwendet, wenn Sie entscheiden möchten, ob ein bestimmter Absturz verarbeitet werden muss oder nicht. Es könnte zum Beispiel einen Absturz auf Systemebene geben, den Sie ignorieren möchten und nicht an das App Center senden wollen.

- (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.
}

Behandelte Fehler

App Center ermöglicht Ihnen auch das Nachverfolgen von Fehlern mithilfe von behandelten Ausnahmen über die trackError-Methode. Eine App kann optional Eigenschaften oder/und Anlagen an einen behandelten Fehlerbericht anfügen, um weiteren Kontext bereitzustellen.

@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)
}

Für Nachverfolgen von Ausnahmen können Sie die Folgende Methode verwenden 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)
}

Wenn Ihnen der Datenschutz des Benutzers wichtig ist, sollten Sie die Benutzerbestätigung erhalten, bevor Sie einen Absturzbericht an das App Center senden. Das SDK stellt eine Callback-Funktion bereit, die App Center Crashes angewiesen ist, auf die Bestätigung des Benutzers zu warten, bevor Absturzberichte gesendet werden.

Wenn Sie sich dafür entschieden haben, sind Sie dafür verantwortlich, die Bestätigung des Benutzers zu erhalten, z. B. über eine Dialogfeldaufforderung mit einer der folgenden Optionen: "Immer senden", " Senden" und "Nicht senden". Basierend auf der Eingabe geben Sie App Center Crashes Anweisungen, und der Absturz wird dann entsprechend behandelt.

Hinweis

Das SDK zeigt hierfür kein Dialogfeld an, die App muss eine eigene Benutzeroberfläche bereitstellen, um die Zustimmung des Benutzers zu verlangen.

Die folgende Methode zeigt, wie ein Benutzerbestätigungshandler eingerichtet wird:

[MSACCrashes setUserConfirmationHandler:(^(NSArray<MSACErrorReport *> *errorReports) {

  // Your code to present your UI to the user, e.g. an NSAlert.
  NSAlert *alert = [[NSAlert alloc] init];
  [alert setMessageText:@"Sorry about that!"];
  [alert setInformativeText:@"Do you want to send an anonymous crash report so we can fix the issue?"];
  [alert addButtonWithTitle:@"Always send"];
  [alert addButtonWithTitle:@"Send"];
  [alert addButtonWithTitle:@"Don't send"];
  [alert setAlertStyle:NSWarningAlertStyle];

  switch ([alert runModal]) {
  case NSAlertFirstButtonReturn:
    [MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationAlways];
    break;
  case NSAlertSecondButtonReturn:
    [MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationSend];
    break;
  case NSAlertThirdButtonReturn:
    [MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationDontSend];
    break;
  default:
    break;
  }

  return YES; // Return YES if the SDK should await user confirmation, otherwise NO.
})];
Crashes.setUserConfirmationHandler({ (errorReports: [ErrorReport]) in

  // Your code to present your UI to the user, e.g. an NSAlert.
  let alert: NSAlert = NSAlert()
  alert.messageText = "Sorry about that!"
  alert.informativeText = "Do you want to send an anonymous crash report so we can fix the issue?"
  alert.addButton(withTitle: "Always send")
  alert.addButton(withTitle: "Send")
  alert.addButton(withTitle: "Don't send")
  alert.alertStyle = NSWarningAlertStyle

  switch (alert.runModal()) {
  case NSAlertFirstButtonReturn:
    Crashes.notify(with: .always)
    break;
  case NSAlertSecondButtonReturn:
    Crashes.notify(with: .send)
    break;
  case NSAlertThirdButtonReturn:
    Crashes.notify(with: .dontSend)
    break;
  default:
    break;
  }

  return true // Return true if the SDK should await user confirmation, otherwise return false.
})

Falls Sie im obigen Handlerblock zurückkehren YES/true , sollte Ihre App die Benutzerberechtigung abrufen und das SDK mit dem Ergebnis mithilfe der folgenden API melden. Wenn Sie hierfür eine Benachrichtigung verwenden, wie im obigen Beispiel, würden Sie sie basierend auf dem Ergebnis (ModalResponse) des runModal Anrufs aufrufen.

// Depending on the user'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.
Crashes.notify(with: .dontSend)
Crashes.notify(with: .send)
Crashes.notify(with: .always)

Aktivieren des Abfangens von Uncaught-Ausnahmen, die im Hauptthread ausgelöst werden

AppKit fängt Ausnahmen ab, die im Hauptthread ausgelöst werden, wodurch verhindert wird, dass die Anwendung unter macOS abstürzt, sodass das SDK diese Abstürze nicht abfangen kann. Um das iOS-Verhalten nachzuahmen, setzen Sie das NSApplicationCrashOnExceptions Flag vor der SDK-Initialisierung, damit die Anwendung bei nicht abgefangenen Ausnahmen abstürzt und das SDK diese melden kann.

[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"NSApplicationCrashOnExceptions" : @YES }];
UserDefaults.standard.register(defaults: ["NSApplicationCrashOnExceptions": true])

Hinweis

Das App Center SDK legt das Flag in den Versionen 1.10.0 und unten automatisch fest. Ab Version 1.11.0 wird dieses Flag nicht mehr automatisch festgelegt.

Deaktivieren der Weiterleitung von Methodenaufrufen der Hauptklasse der Anwendung an App Center Crashes

Das App Center Crashes SDK verwendet swizzling, um seine Integration zu verbessern, indem er selbst einige Methodenaufrufe der Anwendung hauptklasse weiterleite. Das Methoden-Swizzling ist eine Möglichkeit, die Implementierung von Methoden zur Laufzeit zu ändern. Wenn Sie aus irgendeinem Grund kein Swizzling verwenden möchten (z. B. aufgrund einer bestimmten Richtlinie), sollten Sie die reportException: und sendEvent: Methoden der Anwendung selbst überschreiben, damit Crashes Ausnahmen korrekt melden können, die im Hauptthread ausgelöst werden.

  1. Erstellen Sie die Datei ReportExceptionApplication.m , und fügen Sie die folgende Implementierung hinzu:

    @import Cocoa;
    @import AppCenterCrashes;
    
    @interface ReportExceptionApplication : NSApplication
    @end
    
    @implementation ReportExceptionApplication
    
    - (void)reportException:(NSException *)exception {
      [MSACCrashes applicationDidReportException:exception];
      [super reportException:exception];
    }
    
    - (void)sendEvent:(NSEvent *)theEvent {
      @try {
        [super sendEvent:theEvent];
      } @catch (NSException *exception) {
        [self reportException:exception];
      }
    }
    
    @end
    

    Hinweis

    Swift try/catch funktioniert nicht mit NSException. Diese Ausnahmen können nur in Objective-C behandelt werden.

  2. Öffnen Sie die Datei Info.plist , und ersetzen Sie die NSApplication im Feld "Principal"-Klasse durch ihren Anwendungsklassennamen ReportExceptionApplication in diesem Beispiel.

  3. Um das Swizzling im App Center SDK zu deaktivieren, fügen Sie den Schlüssel AppCenterApplicationForwarderEnabled zur Datei Info.plist hinzu und setzen Sie den Wert auf 0.

Abrufen von Informationen zum Sendestatus für ein Absturzprotokoll

Manchmal möchten Sie den Status ihres App-Absturzes kennen. Ein gängiger Anwendungsfall besteht darin, dass Sie die Benutzeroberfläche anzeigen möchten, die den Benutzern sagt, dass Ihre App einen Absturzbericht übermittelt, oder falls ihre App nach dem Start schnell abstürzt, möchten Sie das Verhalten der App anpassen, um sicherzustellen, dass die Absturzprotokolle übermittelt werden können. Das CrashesDelegate-Protokoll definiert drei verschiedene Rückrufe, die Sie in Ihrer App verwenden können, um über die Aktuellen informiert zu werden:

Der folgende Rückruf wird aufgerufen, bevor das SDK ein Absturzprotokoll sendet.

- (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.
}

Falls Netzwerkprobleme oder ein Ausfall auf dem Endpunkt auftreten und Sie die App neu starten, willSendErrorReport wird nach dem Neustart des Prozesses erneut ausgelöst.

Der folgende Rückruf wird aufgerufen, nachdem das SDK erfolgreich ein Absturzprotokoll gesendet hat.

- (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.
}

Der folgende Rückruf wird aufgerufen, wenn das SDK ein Absturzprotokoll nicht senden konnte.

- (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 Der Empfang bedeutet, dass ein nicht wiederherstellbarer Fehler wie z. B. ein 4xx-Code aufgetreten ist. Beispielsweise bedeutet 401, dass das appSecret falsch ist.

Dieser Rückruf wird nicht ausgelöst, wenn es sich um ein Netzwerkproblem handelt. In diesem Fall führt das SDK fortlaufend Wiederholungen durch (und unterbricht diese, während die Netzwerkverbindung unterbrochen ist).

Hinzufügen von Anlagen zu einem Absturzbericht

Sie können einem Absturzbericht Binärdateien und Textdateien hinzufügen. Das SDK sendet sie zusammen mit dem kritischen Fehler, damit Sie sie im App Center Portal sehen können. Der folgende Rückruf wird direkt vor dem Senden des gespeicherten Absturzes von vorherigen Anwendungsstarts aufgerufen. Er wird nicht aufgerufen, wenn der Absturz auftritt. Hier ist ein Beispiel für das Anfügen von Text und einem Bild an einen Absturz:

- (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!]
}

Hinweis

Die Größenbeschränkung beträgt derzeit 7 MB. Beim Versuch, eine größere Anlage zu senden, wird ein Fehler ausgelöst.

Aktivieren oder Deaktivieren von App Center-Abstürzen zur Laufzeit

Sie können App Center-Abstürze zur Laufzeit aktivieren und deaktivieren. Wenn Sie sie deaktivieren, wird im SDK keine Absturzberichterstattung für die App ausgeführt.

[MSACCrashes setEnabled:NO];
Crashes.enabled = false

Um App Center-Abstürze erneut zu aktivieren, verwenden Sie dieselbe API, übergeben YES/true sie aber als Parameter.

[MSACCrashes setEnabled:YES];
Crashes.enabled = true

Der Zustand wird im Speicher des Geräts über Anwendungsstarts hinweg beibehalten.

Hinweis

Diese Methode darf nur verwendet werden, nachdem Crashes gestartet wurde.

Überprüfen, ob App Center Crashes aktiviert ist

Sie können auch überprüfen, ob App Center Crashes aktiviert ist oder nicht:

BOOL enabled = [MSACCrashes isEnabled];
var enabled = Crashes.enabled

Hinweis

Diese Methode darf nur verwendet werden, nachdem Crashes gestartet wurde; vor dem Start wird aber immer false zurückgegeben.

Deaktivieren der Mach-Ausnahmebehandlung

Standardmäßig verwendet App Center Crashes den Mach-Ausnahmehandler, um schwerwiegende Signale, z. B. Stapelüberläufe, über einen Mach-Ausnahmeserver abzufangen.

Die disableMachExceptionHandler-Methode bietet eine Option zum Deaktivieren des Abfangens von schwerwiegenden Signalen über einen Mach-Ausnahmeserver. Wenn Sie den Mach-Ausnahmehandler deaktivieren möchten, sollten Sie diese Methode AUFRUFEN, BEVOR Sie das SDK starten. Ihr typischer Setupcode sieht wie folgt aus:

[MSACCrashes disableMachExceptionHandler];
[MSACAppCenter start:@"{Your App Secret}" withServices:@[[MSACAnalytics class], [MSACCrashes class]]];
Crashes.disableMachExceptionHandler()
AppCenter.start(withAppSecret: "{Your App Secret}", services: [Analytics.self, Crashes.self])