Awarie usługi App Center (macOS)
Ważne
Program Visual Studio App Center ma zostać wycofany 31 marca 2025 r. Mimo że możesz nadal używać programu Visual Studio App Center do momentu jej pełnego wycofania, istnieje kilka zalecanych alternatyw, do których można rozważyć migrację.
Dowiedz się więcej o osiach czasu pomocy technicznej i alternatywach.
Awarie centrum aplikacji automatycznie wygenerują dziennik awarii za każdym razem, gdy aplikacja ulegnie awarii. Dziennik jest najpierw zapisywany w magazynie urządzenia, a gdy użytkownik ponownie uruchomi aplikację, raport o awarii zostanie wysłany do Centrum aplikacji. Zbieranie awarii działa zarówno w przypadku aplikacji beta, jak i na żywo, tj. przesłanych do App Store. Dzienniki awarii zawierają cenne informacje ułatwiające naprawienie awarii.
Jeśli zestaw SDK nie został jeszcze skonfigurowany w aplikacji, postępuj zgodnie z sekcją Wprowadzenie.
Ponadto dzienniki awarii w systemie macOS wymagają symboli symbolicznych, zapoznaj się z dokumentacją diagnostyki centrum aplikacji , która wyjaśnia, jak udostępniać symbole aplikacji.
Uwaga
4.0.0
Wprowadzono zmiany powodujące niezgodność w usłudze App Center. Postępuj zgodnie z sekcją Migrowanie do zestawu APP Center SDK 4.0.0 i nowszych , aby przeprowadzić migrację usługi App Center z poprzednich wersji.
Raportowanie awarii w rozszerzeniach
Usługa App Center obsługuje raportowanie awarii w rozszerzeniach systemu macOS. Użycie jest takie samo jak w aplikacji kontenera.
Generowanie awarii testowej
Usługa App Center Crash udostępnia interfejs API umożliwiający wygenerowanie awarii testowej w celu łatwego testowania zestawu SDK. Ten interfejs API może być używany tylko w aplikacjach testowych/beta i nie wykonuje żadnych czynności w aplikacjach produkcyjnych.
[MSACCrashes generateTestCrash];
Crashes.generateTestCrash()
Uzyskaj więcej informacji o poprzedniej awarii
Usługa App Center Crash ma dwa interfejsy API, które zapewniają więcej informacji na wypadek awarii aplikacji.
Czy w poprzedniej sesji aplikacja otrzymała ostrzeżenie o niskiej ilości pamięci?
W dowolnym momencie po uruchomieniu zestawu SDK możesz sprawdzić, czy aplikacja otrzymała ostrzeżenie o pamięci w poprzedniej sesji:
[MSACCrashes hasReceivedMemoryWarningInLastSession];
Crashes.hasReceivedMemoryWarningInLastSession
Uwaga
Ta metoda musi być używana tylko po Crashes
rozpoczęciu, zawsze będzie zwracać NO
lub false
przed rozpoczęciem.
Uwaga
W niektórych przypadkach urządzenie z małą ilością pamięci nie może wysyłać zdarzeń.
Czy aplikacja uległa awarii w poprzedniej sesji?
W dowolnym momencie po uruchomieniu zestawu SDK możesz sprawdzić, czy aplikacja uległa awarii w poprzednim uruchomieniu:
[MSACCrashes hasCrashedInLastSession];
Crashes.hasCrashedInLastSession
Jest to przydatne w przypadku, gdy chcesz dostosować zachowanie lub interfejs użytkownika aplikacji po wystąpieniu awarii.
Uwaga
Ta metoda musi być używana tylko po MSACCrashes
rozpoczęciu, zawsze będzie zwracać NO
lub false
przed rozpoczęciem.
Szczegóły dotyczące ostatniej awarii
Jeśli aplikacja uległa awarii wcześniej, możesz uzyskać szczegółowe informacje o ostatniej awarii.
MSACErrorReport *crashReport = [MSACCrashes lastSessionCrashReport];
var crashReport = Crashes.lastSessionCrashReport
Uwaga
Ta metoda musi być używana tylko po Crashes
rozpoczęciu. Będzie ona zawsze zwracana nil
przed rozpoczęciem.
W przypadku tego interfejsu API istnieje wiele przypadków użycia. Najczęściej są to osoby, które nazywają ten interfejs API i implementują niestandardowe elementy CrashDelegate.
Dostosowywanie użycia awarii centrum aplikacji
Usługa App Center Crash udostępnia wywołania zwrotne dla deweloperów w celu wykonywania dodatkowych akcji przed i podczas wysyłania dzienników awarii do centrum aplikacji.
Aby dodać zachowanie niestandardowe, należy zastosować CrashesDelegate
protokół -, wszystkie jego metody są opcjonalne.
Zarejestruj się jako pełnomocnik
[MSACCrashes setDelegate:self];
Crashes.delegate = self
Uwaga
Należy ustawić delegata przed wywołaniem metody AppCenter.start
, ponieważ usługa App Center rozpoczyna przetwarzanie awarii natychmiast po uruchomieniu.
Czy awaria powinna zostać przetworzona?
Zaimplementuj metodę crashes:shouldProcessErrorReport:
-w klasie, która przyjmuje CrashesDelegate
-protocol, jeśli chcesz zdecydować, czy określona awaria musi zostać przetworzona, czy nie. Na przykład może wystąpić awaria na poziomie systemu, którą chcesz zignorować i że nie chcesz wysyłać do centrum aplikacji.
- (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.
}
Obsługiwane błędy
Centrum aplikacji umożliwia również śledzenie błędów przy użyciu obsługiwanych wyjątków za pomocą trackError
metody . Aplikacja może opcjonalnie dołączyć właściwości lub/i załączniki do obsługiwanego raportu o błędach w celu zapewnienia dalszego kontekstu.
@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)
}
W przypadku śledzenia wyjątków można użyć trackException
metody:
@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)
}
Poproś użytkownika o zgodę na wysłanie dziennika awarii
Jeśli prywatność użytkownika jest dla Ciebie ważna, możesz uzyskać potwierdzenie użytkownika przed wysłaniem raportu o awarii do Centrum aplikacji. Zestaw SDK uwidacznia wywołanie zwrotne, które informuje usługę App Center Crash o oczekiwaniu na potwierdzenie użytkownika przed wysłaniem raportów o awarii.
Jeśli zdecydujesz się to zrobić, odpowiadasz za uzyskanie potwierdzenia użytkownika, np. za pośrednictwem monitu dialogowego z jedną z następujących opcji: Zawsze wysyłaj, Wysyłaj i nie wysyłaj. Na podstawie danych wejściowych poinformujesz centrum aplikacji o awarii, co należy zrobić, a awaria zostanie odpowiednio obsłużona.
Uwaga
Zestaw SDK nie wyświetla okna dialogowego. Aplikacja musi podać własny interfejs użytkownika, aby poprosić o zgodę użytkownika.
Poniższa metoda pokazuje, jak skonfigurować procedurę obsługi potwierdzenia użytkownika:
[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.
})
W przypadku powrotu YES
/true
w powyższym bloku obsługi aplikacja powinna uzyskać uprawnienie użytkownika i wysłać do zestawu SDK komunikat z wynikiem przy użyciu następującego interfejsu API. Jeśli używasz alertu w tym celu, jak w powyższym przykładzie, wywołasz go na podstawie wyniku wywołania runModal
(ModalResponse).
// 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)
Włącz przechwytywanie nieuchwyconych wyjątków zgłaszanych w głównym wątku
Zestaw AppKit przechwytuje wyjątki zgłaszane w wątku głównym, uniemożliwiając aplikacji awarię w systemie macOS, dzięki czemu zestaw SDK nie może przechwycić tych awarii. Aby naśladować zachowanie systemu iOS, ustaw NSApplicationCrashOnExceptions
flagę przed inicjowaniem zestawu SDK, ta flaga umożliwia aplikacji awarię w przypadku nieumyślnych wyjątków, a zestaw SDK może je zgłaszać.
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"NSApplicationCrashOnExceptions" : @YES }];
UserDefaults.standard.register(defaults: ["NSApplicationCrashOnExceptions": true])
Uwaga
Zestaw SDK usługi App Center ustawia flagę automatycznie w wersjach 1.10.0 i nowszych. Począwszy od wersji 1.11.0 ta flaga nie jest już ustawiana automatycznie.
Wyłączanie przekazywania metod klasy głównej aplikacji do wywołań do centrum aplikacji Ulega awarii
Zestaw SDK awarii w usłudze App Center używawizzlingu, aby ulepszyć integrację przez przekazanie niektórych wywołań metod klasy głównej aplikacji. Metoda swizzling to sposób zmiany implementacji metod w czasie wykonywania. Jeśli z jakiegokolwiek powodu nie chcesz używaćwizzlingu (np. z powodu określonych zasad), należy zastąpić metody i sendEvent:
aplikacji reportException:
w celu poprawnego zgłaszania wyjątków zgłaszanych w wątku głównym.
Utwórz plik ReportExceptionApplication.m i dodaj następującą implementację:
@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
Uwaga
Usługa
try
/catch
Swift nie współpracuje z usługą .NSException
Te wyjątki można obsłużyć tylko w języku Objective-C.Otwórz plik Info.plist i zastąp ciąg NSApplication w polu Class Principal nazwą klasy aplikacji ReportExceptionApplication w tym przykładzie.
Aby wyłączyć swizzling w zestawie SDK usługi App Center, dodaj
AppCenterApplicationForwarderEnabled
klucz do pliku Info.plist i ustaw wartość0
na .
Uzyskiwanie informacji o stanie wysyłania dziennika awarii
Czasami chcesz znać stan awarii aplikacji. Typowy przypadek użycia polega na tym, że możesz pokazać interfejs użytkownika, który informuje użytkowników, że aplikacja przesyła raport o awarii lub w przypadku, gdy aplikacja ulega awarii szybko po uruchomieniu, chcesz dostosować zachowanie aplikacji, aby upewnić się, że dzienniki awarii można przesłać. Protokół CrashesDelegate
-protocol definiuje trzy różne wywołania zwrotne, których można użyć w aplikacji, aby otrzymywać powiadomienia o tym, co się dzieje:
Następujące wywołanie zwrotne zostanie wywołane przed wysłaniem dziennika awarii przez zestaw 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.
}
W przypadku wystąpienia problemów z siecią lub awarii punktu końcowego i ponowne uruchomienie aplikacji willSendErrorReport
zostanie ponownie wyzwolone po ponownym uruchomieniu procesu.
Następujące wywołanie zwrotne zostanie wywołane po pomyślnym wysłaniu dziennika awarii zestawu 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.
}
Następujące wywołanie zwrotne zostanie wywołane, jeśli zestaw SDK nie może wysłać dziennika awarii
- (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.
}
Odbieranie didFailSendingErrorReport
oznacza, że wystąpił błąd niemożliwy do odzyskania, taki jak kod 4xx . Na przykład 401 oznacza, że wartość jest nieprawidłowa appSecret
.
To wywołanie zwrotne nie jest wyzwalane, jeśli jest to problem z siecią. W takim przypadku zestaw SDK ponawia próbę (a także wstrzymuje ponawianie próby, gdy połączenie sieciowe nie działa).
Dodawanie załączników do raportu o awarii
Możesz dodać załączniki binarne i tekstowe do raportu o awarii. Zestaw SDK wyśle je wraz z awarią, aby można było je zobaczyć w portalu centrum aplikacji. Następujące wywołanie zwrotne zostanie wywołane bezpośrednio przed wysłaniem przechowywanej awarii z poprzednich uruchomień aplikacji. Nie będzie wywoływana, gdy wystąpi awaria. Oto przykład dołączania tekstu i obrazu do awarii:
- (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!]
}
Uwaga
Limit rozmiaru wynosi obecnie 7 MB. Próba wysłania większego załącznika spowoduje wyzwolenie błędu.
Włączanie lub wyłączanie awarii usługi App Center w czasie wykonywania
Możesz włączyć i wyłączyć awarie usługi App Center w czasie wykonywania. Jeśli ją wyłączysz, zestaw SDK nie będzie wykonywać żadnych raportów o awarii dla aplikacji.
[MSACCrashes setEnabled:NO];
Crashes.enabled = false
Aby ponownie włączyć awarie usługi App Center, użyj tego samego interfejsu API, ale przekaż YES
/true
go jako parametr.
[MSACCrashes setEnabled:YES];
Crashes.enabled = true
Stan jest utrwalany w magazynie urządzenia w ramach uruchamiania aplikacji.
Uwaga
Ta metoda musi być używana tylko po Crashes
rozpoczęciu.
Sprawdzanie, czy w centrum aplikacji jest włączona awaria
Możesz również sprawdzić, czy usługa App Center Ulega awarii jest włączona, czy nie:
BOOL enabled = [MSACCrashes isEnabled];
var enabled = Crashes.enabled
Uwaga
Ta metoda musi być używana tylko po Crashes
rozpoczęciu. Będzie ona zawsze zwracana false
przed rozpoczęciem.
Wyłączanie obsługi wyjątków mach
Domyślnie usługa App Center Crash używa procedury obsługi wyjątków mach do przechwytywania sygnałów krytycznych, np. przepełnienia stosu za pośrednictwem serwera wyjątków mach.
Metoda disableMachExceptionHandler
-zapewnia opcję wyłączenia przechwytywania sygnałów krytycznych za pośrednictwem serwera wyjątków mach. Jeśli chcesz wyłączyć procedurę obsługi wyjątków mach, należy wywołać tę metodę PRZED uruchomieniem zestawu SDK. Typowy kod konfiguracji wygląda następująco:
[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])