Arresti anomali di App Center (iOS)
Importante
Visual Studio App Center è pianificato per il ritiro il 31 marzo 2025. Anche se è possibile continuare a usare Visual Studio App Center fino a quando non viene completamente ritirato, esistono diverse alternative consigliate a cui è possibile prendere in considerazione la migrazione.
Altre informazioni sulle sequenze temporali di supporto e sulle alternative.
Gli arresti anomali di App Center genereranno automaticamente un log di arresto anomalo ogni volta che l'app si arresta in modo anomalo. Il log viene prima scritto nella risorsa di archiviazione del dispositivo e quando l'utente avvia nuovamente l'app, il report di arresto anomalo verrà inviato ad App Center. La raccolta di arresti anomali funziona sia per le app beta che per quelle attive, ovvero quelle inviate al App Store. I log di arresto anomalo contengono informazioni utili per risolvere l'arresto anomalo del sistema.
Se non è ancora stato configurato l'SDK nell'applicazione, seguire la sezione Introduzione.
Inoltre, i log di arresto anomalo in iOS richiedono simbolicamente, vedere la documentazione di Diagnostica di App Center che spiega come fornire simboli per l'app.
Nota
L'SDK non inoltra alcun log di arresto anomalo se è collegato al debugger. Assicurarsi che il debugger non sia collegato quando si arresta l'arresto anomalo dell'app.
Nota
Per ricevere tracce dello stack simbolico correttamente, assicurarsi che bitcode sia disabilitato. Altre informazioni su bitcode sono disponibili nella documentazione relativa ai simboli iOS di App Center.
Nota
4.0.0
Nella versione di App Center sono state introdotte modifiche di rilievo. Seguire la sezione Eseguire la migrazione ad App Center SDK 4.0.0 e versioni successive per eseguire la migrazione di App Center dalle versioni precedenti.
App Center supporta la segnalazione degli arresti anomali nelle estensioni iOS. L'utilizzo è identico a quello dell'applicazione contenitore.
Gli arresti anomali di App Center offrono un'API per generare un arresto anomalo del test per semplificare il test dell'SDK. Questa API può essere usata solo nelle app di test/beta e non esegue alcuna operazione nelle app di produzione.
[MSACCrashes generateTestCrash];
Crashes.generateTestCrash()
Gli arresti anomali di App Center hanno due API che forniscono altre informazioni in caso di arresto anomalo dell'app.
In qualsiasi momento dopo l'avvio dell'SDK, è possibile verificare se l'app ha ricevuto un avviso di memoria nella sessione precedente:
[MSACCrashes hasReceivedMemoryWarningInLastSession];
Crashes.hasReceivedMemoryWarningInLastSession
Nota
Questo metodo deve essere utilizzato solo dopo Crashes
l'avvio, verrà sempre restituito NO
o false
prima dell'avvio.
Nota
In alcuni casi, un dispositivo con memoria insufficiente non può inviare eventi.
In qualsiasi momento dopo l'avvio dell'SDK, è possibile verificare se l'app si è arrestata in modo anomalo nell'avvio precedente:
[MSACCrashes hasCrashedInLastSession];
Crashes.hasCrashedInLastSession
Questo è utile nel caso in cui vuoi modificare il comportamento o l'interfaccia utente della tua app dopo che si è verificato un arresto anomalo.
Nota
Questo metodo deve essere utilizzato solo dopo MSACCrashes
l'avvio, verrà sempre restituito NO
o false
prima dell'avvio.
Se l'app si è arrestata in modo anomalo in precedenza, è possibile ottenere dettagli sull'ultimo arresto anomalo.
MSACErrorReport *crashReport = [MSACCrashes lastSessionCrashReport];
var crashReport = Crashes.lastSessionCrashReport
Nota
Questo metodo deve essere utilizzato solo dopo Crashes
l'avvio, ma restituirà nil
sempre prima dell'avvio.
Esistono numerosi casi d'uso per questa API, quello più comune è rappresentato dalle persone che chiamano questa API e implementano crashesDelegate personalizzati.
Gli arresti anomali di App Center forniscono callback per gli sviluppatori per eseguire azioni aggiuntive prima e quando si inviano log di arresto anomalo ad App Center.
Per aggiungere il comportamento personalizzato, è necessario adottare il CrashesDelegate
protocollo -, tutti i relativi metodi sono facoltativi.
[MSACCrashes setDelegate:self];
Crashes.delegate = self
Nota
È necessario impostare il delegato prima di chiamare AppCenter.start
, perché App Center avvia l'elaborazione si arresta in modo anomalo immediatamente dopo l'avvio.
Implementare il crashes:shouldProcessErrorReport:
metodo -nella classe che adotta il CrashesDelegate
protocollo -se si vuole decidere se un determinato arresto anomalo deve essere elaborato o meno. Ad esempio, potrebbe verificarsi un arresto anomalo a livello di sistema che si vuole ignorare e che non si vuole inviare ad 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 consente anche di tenere traccia degli errori usando le eccezioni gestite tramite trackError
il metodo . Un'app può facoltativamente allegare proprietà o/e allegati a un report degli errori gestito per fornire ulteriore contesto.
@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)
}
Per tenere traccia delle eccezioni, è possibile usare il trackException
metodo :
@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)
}
Se la privacy dell'utente è importante per te, potresti voler ricevere una conferma dell'utente prima di inviare un report di arresto anomalo al Centro app. L'SDK espone un callback che indica agli arresti anomali di App Center di attendere la conferma dell'utente prima di inviare eventuali segnalazioni di arresto anomalo.
Se si sceglie di farlo, si è responsabili di ottenere la conferma dell'utente, ad esempio tramite una richiesta di dialogo con una delle opzioni seguenti: Invia sempre, Invia e Non inviare. In base all'input, si indicherà agli arresti anomali di App Center cosa fare e l'arresto anomalo verrà quindi gestito di conseguenza.
Nota
L'SDK non visualizza una finestra di dialogo per questa operazione, l'app deve fornire la propria interfaccia utente per richiedere il consenso dell'utente.
Nota
L'app non deve chiamare notifyWithUserConfirmation
in modo esplicito se non implementa una finestra di dialogo di conferma dell'utente. Il modulo Arresti anomali gestirà l'invio implicito dei log.
Il metodo seguente illustra come configurare un gestore di conferma utente:
[MSACCrashes setUserConfirmationHandler:(^(NSArray<MSACErrorReport *> *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) {
[MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationDontSend];
}]];
[alertController
addAction:[UIAlertAction actionWithTitle:@"Send"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationSend];
}]];
[alertController
addAction:[UIAlertAction actionWithTitle:@"Always send"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationAlways];
}]];
// 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.
})];
Crashes.setUserConfirmationHandler({ (errorReports: [ErrorReport]) 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
Crashes.notify(with: .dontSend)
})
alertController.addAction(UIAlertAction(title: "Send", style: .default) {_ in
Crashes.notify(with: .send)
})
alertController.addAction(UIAlertAction(title: "Always send", style: .default) {_ in
Crashes.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.
})
Nel caso in cui venga restituito YES
/true
nel blocco del gestore precedente, l'app deve ottenere l'autorizzazione utente e invitare l'SDK con il risultato usando l'API seguente. Se si usa un avviso per questo, come nell'esempio precedente, è necessario chiamarlo dall'interno dell'implementazione del alertView:clickedButtonAtIndex:
callback .
// Depending on the users'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)
A volte, vuoi conoscere lo stato dell'arresto anomalo dell'app. Un caso d'uso comune è che potresti voler mostrare all'interfaccia utente che indica agli utenti che l'app sta inviando un report di arresto anomalo o, nel caso in cui l'app si arresti in modo anomalo dopo l'avvio, vuoi modificare il comportamento dell'app per assicurarti che i log di arresto anomalo possano essere inviati. Il CrashesDelegate
protocollo -definisce tre callback diversi che puoi usare nella tua app per ricevere una notifica di cosa sta succedendo:
- (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.
}
In caso di problemi di rete o interruzione dell'endpoint e il riavvio dell'app viene willSendErrorReport
attivato di nuovo dopo il riavvio del processo.
Il callback seguente verrà richiamato dopo che l'SDK ha inviato correttamente un log di arresto anomalo
- (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.
}
- (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.
}
La ricezione didFailSendingErrorReport
indica che si è verificato un errore non recuperabile, ad esempio un codice 4xx . Ad esempio, 401 indica che l'errore appSecret
è.
Questo callback non viene attivato se si tratta di un problema di rete. In questo caso, l'SDK continua a ritentare (e sospende anche i tentativi mentre la connessione di rete è inattiva).
È possibile aggiungere allegati binari e di testo a un report di arresto anomalo del sistema. L'SDK li invierà insieme all'arresto anomalo in modo da poterli visualizzare nel portale di App Center. Il callback seguente verrà richiamato immediatamente prima di inviare l'arresto anomalo archiviato dall'avvio dell'applicazione precedente. Non verrà richiamato quando si verifica l'arresto anomalo. Ecco un esempio di come allegare testo e un'immagine a un arresto anomalo:
- (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!]
}
Nota
Il limite di dimensioni è attualmente 7 MB. Il tentativo di inviare un allegato più grande attiverà un errore.
È possibile abilitare e disabilitare gli arresti anomali del Centro app in fase di esecuzione. Se la disabilita, l'SDK non eseguirà alcuna segnalazione di arresto anomalo per l'app.
[MSACCrashes setEnabled:NO];
Crashes.enabled = false
Per abilitare di nuovo gli arresti anomali di App Center, usare la stessa API ma passare YES
/true
come parametro.
[MSACCrashes setEnabled:YES];
Crashes.enabled = true
Lo stato viene mantenuto nello spazio di archiviazione del dispositivo tra i lanci dell'applicazione.
Nota
Questo metodo deve essere usato solo dopo Crashes
l'avvio.
È anche possibile verificare se gli arresti anomali di App Center sono abilitati o meno:
BOOL enabled = [MSACCrashes isEnabled];
var enabled = Crashes.enabled
Nota
Questo metodo deve essere usato solo dopo Crashes
l'avvio, verrà sempre restituito false
prima dell'avvio.
Per impostazione predefinita, App Center Arresti anomali usa il gestore eccezioni Mach per rilevare segnali irreversibili, ad esempio gli overflow dello stack, tramite un server di eccezioni Mach.
Il disableMachExceptionHandler
metodo -offre un'opzione per disabilitare l'individuazione dei segnali irreversibili tramite un server di eccezione Mach. Se si vuole disabilitare il gestore eccezioni Mach, è necessario chiamare questo metodo PRIMA di avviare l'SDK. Il codice di installazione tipico sarà simile al seguente:
[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])