Plantages app Center (macOS)
Important
Visual Studio App Center doit être mis hors service le 31 mars 2025. Bien que vous puissiez continuer à utiliser Visual Studio App Center jusqu’à ce qu’il soit entièrement mis hors service, il existe plusieurs alternatives recommandées vers lesquelles vous pouvez envisager de migrer.
En savoir plus sur les chronologies et les alternatives de support.
Les incidents app Center génèrent automatiquement un journal des incidents 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 bêta et actives, c’est-à-dire celles soumises au App Store. Les journaux d’incident contiennent des informations précieuses pour vous aider à résoudre le blocage.
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 symbolisation, case activée la documentation de diagnostic d’App Center qui explique comment fournir des symboles pour votre application.
Notes
Dans la 4.0.0
version d’App Center, des changements cassants ont été introduits. Suivez la section Migrer vers app Center SDK 4.0.0 et versions ultérieures pour migrer App Center à partir des versions précédentes.
App Center prend en charge les rapports d’incident dans les extensions macOS. L’utilisation est la même que dans l’application conteneur.
App Center Crashs vous fournit une API pour générer un plantage de test afin de tester facilement le 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()
App Center Crashs a deux API qui vous donnent plus d’informations en cas de plantage de votre application.
L’application a-t-elle reçu un avertissement de mémoire insuffisante lors de la session précédente ?
À tout moment après le démarrage du Kit de développement logiciel (SDK), vous pouvez case activée si l’application a reçu un avertissement de mémoire lors de la session précédente :
[MSACCrashes hasReceivedMemoryWarningInLastSession];
Crashes.hasReceivedMemoryWarningInLastSession
Notes
Cette méthode ne doit être utilisée qu’après Crashes
le démarrage. Elle retourne NO
toujours ou false
avant le début.
Notes
Dans certains cas, un appareil avec une mémoire insuffisante ne peut pas envoyer d’événements.
À tout moment après le démarrage du Kit de développement logiciel (SDK), vous pouvez case activée si l’application s’est plantée lors du lancement précédent :
[MSACCrashes hasCrashedInLastSession];
Crashes.hasCrashedInLastSession
Cela s’avère utile si vous souhaitez ajuster le comportement ou l’interface utilisateur de votre application après un incident.
Notes
Cette méthode ne doit être utilisée qu’après MSACCrashes
le démarrage. Elle retourne NO
toujours ou false
avant le début.
Si votre application s’est plantée précédemment, vous pouvez obtenir des détails sur le dernier incident.
MSACErrorReport *crashReport = [MSACCrashes lastSessionCrashReport];
var crashReport = Crashes.lastSessionCrashReport
Notes
Cette méthode ne doit être utilisée qu’après Crashes
avoir démarré. Elle sera toujours retournée nil
avant le début.
Il existe de nombreux cas d’utilisation pour cette API, le plus courant étant les personnes qui appellent cette API et implémentent leur crashDelegate personnalisé.
App Center Crash fournit des rappels permettant aux développeurs d’effectuer des actions supplémentaires avant et lors de l’envoi des journaux d’incident à App Center.
Pour ajouter votre comportement personnalisé, vous devez adopter le CrashesDelegate
protocole -, toutes ses méthodes sont facultatives.
[MSACCrashes setDelegate:self];
Crashes.delegate = self
Notes
Vous devez définir le délégué avant d’appeler AppCenter.start
, car App Center commence le traitement se bloque immédiatement après le démarrage.
Implémentez la crashes:shouldProcessErrorReport:
méthode -dans la classe qui adopte le CrashesDelegate
protocole -si vous souhaitez décider si un incident particulier doit être traité ou non. Par exemple, il peut y avoir un incident 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.
}
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’erreurs 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 les exceptions de suivi, vous pouvez utiliser la trackException
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é des utilisateurs est importante pour vous, vous pouvez obtenir une confirmation de l’utilisateur avant d’envoyer un rapport d’incident à App Center. Le Kit de développement logiciel (SDK) expose un rappel qui indique à App Center Crashs d’attendre la confirmation de l’utilisateur avant d’envoyer des rapports d’incident.
Si vous choisissez 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 de l’entrée, vous indiquez à App Center crash ce qu’il faut faire et le plantage sera ensuite géré en conséquence.
Notes
Le Kit de développement logiciel (SDK) n’affiche pas de boîte de dialogue pour cela. L’application doit fournir sa propre interface utilisateur pour demander le consentement de l’utilisateur.
La méthode suivante montre comment configurer un gestionnaire de confirmation 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 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)
AppKit intercepte les exceptions levées sur le thread main, empêchant l’application de se bloquer sur macOS, de sorte que le KIT de développement logiciel (SDK) ne peut pas intercepter ces blocages. Pour imiter le comportement iOS, définissez NSApplicationCrashOnExceptions
l’indicateur avant l’initialisation du KIT de développement logiciel (SDK), cet indicateur permet à l’application de se bloquer sur des exceptions non interceptée et le KIT de développement logiciel (SDK) peut les signaler.
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"NSApplicationCrashOnExceptions" : @YES }];
UserDefaults.standard.register(defaults: ["NSApplicationCrashOnExceptions": true])
Notes
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 l’application main classe vers App Center Plantages
Le Kit de développement logiciel (SDK) App Center crash utilise le swizzling pour améliorer son intégration en transférant lui-même certains des appels de méthodes de l’application main classe. Le swizzling de méthode 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 swizzling (par exemple, en raison d’une stratégie spécifique), vous devez remplacer vous-même les méthodes et sendEvent:
de reportException:
l’application afin que les incidents signalent correctement les exceptions levées sur le thread main.
Créez le 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
Notes
Swift ne
try
/catch
fonctionne pas avec .NSException
Ces exceptions ne peuvent être gérées que dans Objective-C.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.
Pour désactiver la swizzling dans le Kit de développement logiciel (SDK) App Center, ajoutez la
AppCenterApplicationForwarderEnabled
clé au fichier Info.plist et définissez la valeur sur0
.
Parfois, vous souhaitez connaître le status de l’incident de votre application. Un cas d’usage courant est que vous souhaitez 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 envoyés. 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 sera appelé avant que le KIT de développement logiciel (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
est à nouveau déclenché 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 sera appelé si le KIT de développement logiciel (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.
}
didFailSendingErrorReport
La réception 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 interrompt également les nouvelles tentatives lorsque la connexion réseau est interrompue).
Vous pouvez ajouter des pièces jointes binaires et de texte à un rapport d’incident. Le Kit de développement logiciel (SDK) les envoie avec le plantage afin que vous puissiez les voir dans le portail App Center. Le rappel suivant sera appelé juste avant d’envoyer le blocage stocké à partir des lancements précédents de l’application. Il ne sera pas appelé lorsque l’incident se produit. Voici un exemple montrant comment joindre du texte et une 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!]
}
Notes
La limite de taille est actuellement de 7 Mo. La tentative d’envoi d’une pièce jointe plus volumineuse déclenche une erreur.
Vous pouvez activer et désactiver les incidents App Center au moment de l’exécution. Si vous le désactivez, le SDK n’effectuera aucun rapport d’incident pour l’application.
[MSACCrashes setEnabled:NO];
Crashes.enabled = false
Pour réactiver les incidents YES
/true
App Center, utilisez la même API, mais passez en tant que paramètre.
[MSACCrashes setEnabled:YES];
Crashes.enabled = true
L’état est conservé dans le stockage de l’appareil au cours des lancements d’application.
Notes
Cette méthode ne doit être utilisée qu’après Crashes
le démarrage.
Vous pouvez également case activée si les incidents App Center sont activés ou non :
BOOL enabled = [MSACCrashes isEnabled];
var enabled = Crashes.enabled
Notes
Cette méthode ne doit être utilisée qu’après Crashes
le démarrage. Elle est toujours retournée false
avant le démarrage.
Par défaut, App Center Crash utilise le gestionnaire d’exceptions Mach pour intercepter les signaux mortels, par exemple les dépassements de capacité de la pile, via un serveur d’exceptions Mach.
La disableMachExceptionHandler
méthode -fournit une option permettant de désactiver l’interception des signaux fatals 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 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])