Partager via


Plantages d’App Center (macOS)

Important

Visual Studio App Center a été mis hors service le 31 mars 2025, à l’exception des fonctionnalités d’analyse et de diagnostic, qui continueront d’être prises en charge jusqu’au 30 juin 2026. En savoir plus.

App Center Crashes génèrera automatiquement un journal des crashs chaque fois que votre application se bloque. Le journal est d’abord écrit dans le stockage de l’appareil et lorsque l’utilisateur redémarre l’application, le rapport d’incident est envoyé à App Center. La collecte des incidents fonctionne à la fois pour les applications en étapes bêta et production, c'est-à-dire celles soumises sur l'App Store. Les journaux de crash contiennent des informations précieuses pour vous aider à résoudre le crash.

Suivez la section Prise en main si vous n’avez pas encore configuré le Kit de développement logiciel (SDK) dans votre application.

En outre, les journaux d’incident sur macOS nécessitent une symbolique, consultez la documentation des diagnostics App Center qui explique comment fournir des symboles pour votre application.

Remarque

Des modifications importantes ont été introduites dans la version 4.0.0 d'App Center. Suivez la section Migrate to App Center SDK 4.0.0 et versions ultérieures pour migrer App Center à partir des versions précédentes.

Rapports d’incident dans les extensions

App Center prend en charge les rapports d’incident dans les extensions macOS. L’utilisation est la même que dans l’application conteneur.

Générer un plantage de test

App Center Crash vous fournit une API pour générer un plantage de test pour faciliter le test du Kit de développement logiciel (SDK). Cette API ne peut être utilisée que dans les applications de test/bêta et ne fera rien dans les applications de production.

[MSACCrashes generateTestCrash];
Crashes.generateTestCrash()

Obtenir plus d’informations sur un incident précédent

App Center Crash a deux API qui vous donnent plus d’informations au cas où votre application s’est écrasée.

L’application a-t-elle reçu un avertissement de mémoire faible dans la session précédente ?

À tout moment après avoir démarré le Kit de développement logiciel (SDK), vous pouvez vérifier si l’application a reçu un avertissement de mémoire dans la session précédente :

[MSACCrashes hasReceivedMemoryWarningInLastSession];
Crashes.hasReceivedMemoryWarningInLastSession

Remarque

Cette méthode ne doit être utilisée qu'après que Crashes ait été démarré ; elle renverra toujours NO ou false avant le démarrage.

Remarque

Dans certains cas, un appareil avec une mémoire insuffisante ne peut pas envoyer d’événements.

L’application s’est-elle bloquée dans la session précédente ?

À tout moment après avoir démarré le Kit de développement logiciel (SDK), vous pouvez vérifier si l’application s’est bloquée lors du lancement précédent :

[MSACCrashes hasCrashedInLastSession];
Crashes.hasCrashedInLastSession

Cela est pratique si vous souhaitez ajuster le comportement ou l’interface utilisateur de votre application une fois qu’un incident s’est produit.

Remarque

Cette méthode ne doit être utilisée qu'après que MSACCrashes ait été démarré ; elle renverra toujours NO ou false avant le démarrage.

Détails sur le dernier incident

Si votre application s’est écrasée précédemment, vous pouvez obtenir des détails sur le dernier incident.

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

Remarque

Cette méthode ne doit être utilisée qu’une fois Crashes démarrée, elle retourne nil toujours avant le début.

Il existe de nombreux cas d’usage pour cette API, le plus courant sont les personnes qui appellent cette API et implémentent leur CrashesDelegate personnalisé.

Personnalisez votre utilisation des pannes d’App Center

App Center Crash fournit des rappels aux développeurs pour effectuer des actions supplémentaires avant et lors de l’envoi de journaux d’incident à App Center.

Pour ajouter votre comportement personnalisé, vous devez adopter le CrashesDelegateprotocole -, toutes ses méthodes sont facultatives.

S’inscrire en tant que délégué

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

Remarque

Vous devez définir le délégué avant d’appeler AppCenter.start, car App Center commence le traitement des plantages dès le démarrage.

La panne doit-elle être traitée ?

Implémentez la crashes:shouldProcessErrorReport:méthode -dans la classe qui adopte le CrashesDelegateprotocole -si vous souhaitez décider si un incident particulier doit être traité ou non. Par exemple, il peut y avoir un blocage au niveau du système que vous souhaitez ignorer et que vous ne souhaitez pas envoyer à 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.
}

Erreurs gérées

App Center vous permet également de suivre les erreurs à l’aide d’exceptions gérées via trackError la méthode. Une application peut éventuellement attacher des propriétés ou/et des pièces jointes à un rapport d’erreur géré pour fournir un contexte supplémentaire.

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

Pour suivre les exceptions, vous pouvez utiliser trackException la méthode :

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

Si la confidentialité de l’utilisateur est importante pour vous, vous pouvez obtenir la confirmation de l’utilisateur avant d’envoyer un rapport d’incident à App Center. Le Kit de développement logiciel (SDK) expose une fonction de rappel qui indique à App Center Crashes d'attendre la confirmation de l’utilisateur avant d’envoyer tout rapport d’incident.

Si vous avez choisi de le faire, vous êtes responsable de l’obtention de la confirmation de l’utilisateur, par exemple via une invite de dialogue avec l’une des options suivantes : Toujours envoyer, envoyer et ne pas envoyer. En fonction des données fournies, vous allez indiquer à App Center Crashes ce qu’il doit faire et le plantage sera ensuite géré en conséquence.

Remarque

Le Kit de développement logiciel (SDK) n’affiche pas de boîte de dialogue pour cela, l’application doit fournir son propre interface utilisateur pour demander le consentement de l’utilisateur.

La méthode suivante montre comment configurer un gestionnaire de confirmation d’utilisateur :

[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.
})

Si vous revenez YES/true dans le bloc de gestionnaire ci-dessus, votre application doit obtenir l’autorisation de l’utilisateur et envoyer un message au Kit de développement logiciel (SDK) avec le résultat à l’aide de l’API suivante. Si vous utilisez une alerte pour cela, comme nous le faisons dans l’exemple ci-dessus, vous l’appelez en fonction du résultat (ModalResponse) de l’appel runModal .

// 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)

Activer l’interception d’exceptions non interceptables levées sur le thread principal

AppKit intercepte les exceptions levées sur le thread principal, empêchant l’application de se bloquer sur macOS, afin que le KIT de développement logiciel (SDK) ne puisse pas intercepter ces incidents. Pour imiter le comportement iOS, définissez l’indicateur NSApplicationCrashOnExceptions avant l’initialisation du SDK, cet indicateur permet à l’application de se bloquer sur des exceptions non interceptables et le SDK peut les signaler.

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

Remarque

Le Kit de développement logiciel (SDK) App Center définit automatiquement l’indicateur dans les versions 1.10.0 et ultérieures. À compter de la version 1.11.0, cet indicateur n’est plus défini automatiquement.

Désactiver le transfert des appels de méthodes de la classe principale de l’application aux incidents app Center

Le Kit de développement logiciel (SDK) App Center Crash utilise swizzling pour améliorer son intégration en transférant lui-même certains des appels de méthodes de la classe principale de l’application. La méthode swizzling est un moyen de modifier l’implémentation des méthodes au moment de l’exécution. Si, pour une raison quelconque, vous ne souhaitez pas utiliser le swizzling (par exemple, en raison d'une politique spécifique), vous devez remplacer vous-même les méthodes reportException: et sendEvent: de l’application afin que les rapports d'incidents signalent correctement les exceptions levées sur le fil principal.

  1. Créez un fichier ReportExceptionApplication.m et ajoutez l’implémentation suivante :

    @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
    

    Remarque

    try / catchSwift ne fonctionne pas avec NSException. Ces exceptions peuvent être gérées uniquement dans Objective-C.

  2. Ouvrez le fichier Info.plist et remplacez NSApplication dans le champ de classe principal par le nom de votre classe d’application , ReportExceptionApplication dans cet exemple.

  3. Pour désactiver swizzling dans le Kit de développement logiciel (SDK) App Center, ajoutez la AppCenterApplicationForwarderEnabled clé au fichier Info.plist et définissez la valeur 0sur .

Obtenir des informations sur l’état d’envoi d’un journal d’incident

Il arrive que vous souhaitiez connaître l'état du crash de votre application. Un cas d’usage courant est que vous souhaiterez peut-être afficher l’interface utilisateur qui indique aux utilisateurs que votre application envoie un rapport d’incident ou, si votre application se bloque rapidement après le lancement, vous souhaitez ajuster le comportement de l’application pour vous assurer que les journaux d’incident peuvent être soumis. Le CrashesDelegate protocole définit trois rappels différents que vous pouvez utiliser dans votre application pour être informé de ce qui se passe :

Le rappel suivant est appelé avant que le SDK envoie un journal d’incident

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

Si nous avons des problèmes réseau ou une panne sur le point de terminaison, et que vous redémarrez l’application, willSendErrorReport elle est déclenchée à nouveau après le redémarrage du processus.

Le rappel suivant sera appelé une fois que le Kit de développement logiciel (SDK) a envoyé un journal d’incident avec succès

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

Le rappel suivant est appelé si le SDK n’a pas pu envoyer un journal d’incident

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

Recevoir didFailSendingErrorReport signifie qu'une erreur non récupérable, telle qu'un code 4xx, s'est produite. Par exemple, 401 signifie que le appSecret est incorrect.

Ce rappel n’est pas déclenché s’il s’agit d’un problème réseau. Dans ce cas, le Kit de développement logiciel (SDK) continue de réessayer (et suspend également les nouvelles tentatives pendant que la connexion réseau est en panne).

Ajouter des pièces jointes à un rapport d’incident

Vous pouvez ajouter des pièces jointes binaires et textuelles à un rapport de plantage. Le SDK les enverra avec le rapport de plantage afin que vous puissiez les voir dans le portail App Center. Le callback suivant sera invoqué juste avant d’envoyer le crash stocké suite aux lancements précédents de l’application. Il ne sera pas appelé lorsque la panne se produit. Voici un exemple d’attachement de texte et d’image à un incident :

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

Remarque

La limite de taille est actuellement de 7 Mo. La tentative d’envoi d’une pièce jointe plus volumineuse déclenche une erreur.

Activer ou désactiver les crashs d’App Center au moment de l'exécution

Vous pouvez activer et désactiver les plantages d'App Center lors de l’exécution. Si vous le désactivez, le Kit de développement logiciel (SDK) ne produit aucun rapport d’incident pour l’application.

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

Pour réactiver les rapports de plantage d'App Center, utilisez la même API, mais passez YES/true comme paramètre.

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

L’état est conservé dans le stockage de l’appareil dans les lancements d’application.

Remarque

Cette méthode ne doit être utilisée qu’après le démarrage de Crashes.

Vérifier si les blocages d’App Center sont activés

Vous pouvez également vérifier si les crashs d'App Center sont activé ou non.

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

Remarque

Cette méthode ne doit être utilisée qu’une fois Crashes démarrée, elle retourne false toujours avant le début.

Désactivation de la gestion des exceptions Mach

Par défaut, App Center Crashes utilise le gestionnaire d’exceptions Mach pour intercepter les signaux irrécupérables, tels que les débordements de pile, via un serveur d’exceptions Mach.

La méthode disableMachExceptionHandler fournit une option permettant de désactiver la capture des signaux irrécupérables via un serveur d’exceptions Mach. Si vous souhaitez désactiver le gestionnaire d’exceptions Mach, vous devez appeler cette méthode AVANT de démarrer le Kit de développement logiciel (SDK). Votre code d’installation classique se présente comme suit :

[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])