Сбои центра приложений (tvOS)
Важно!
Прекращение поддержки Центра приложений Visual Studio запланировано на 31 марта 2025 г. Хотя вы можете продолжать использовать Центр приложений Visual Studio до полного прекращения его использования, существует несколько рекомендуемых вариантов, на которые можно перейти.
Узнайте больше о сроках поддержки и альтернативных вариантах.
При сбоях Центра приложений автоматически создается журнал сбоев при каждом сбое приложения. Сначала журнал записывается в хранилище устройства, и когда пользователь снова запустит приложение, отчет о сбое будет отправлен в Центр приложений. Сбор сбоев работает как для бета-версии, так и для динамических приложений, т. е. для приложений, отправленных в App Store. Журналы сбоев содержат ценные сведения, которые помогут устранить сбой.
Если вы еще не настроили пакет SDK в приложении, следуйте инструкциям в разделе начало работы.
Кроме того, журналы аварийного завершения в tvOS требуют символики, проверка документацию по диагностике Центра приложений, в которых объясняется, как предоставить символы для приложения.
Примечание
Чтобы получить правильно символьные трассировки стека, убедитесь, что бит-код отключен. Дополнительные сведения о бит-коде см. в документации по символике iOS в Центре приложений.
Примечание
4.0.0
В версии Центра приложений были введены критические изменения. Следуйте указаниям в разделе Миграция на пакет SDK 4.0.0 и более поздних версий Центра приложений , чтобы перенести Центр приложений из предыдущих версий.
Сбои Центра приложений предоставляют API для создания тестового сбоя для простого тестирования пакета SDK. Этот API можно использовать только в тестовых или бета-версиях приложений и не будет выполнять никаких действий в рабочих приложениях.
[MSACCrashes generateTestCrash];
Crashes.generateTestCrash()
При сбоях Центра приложений есть два API, которые предоставляют дополнительные сведения на случай сбоя приложения.
В любое время после запуска пакета SDK можно проверка, если приложение получило предупреждение о памяти в предыдущем сеансе:
[MSACCrashes hasReceivedMemoryWarningInLastSession];
Crashes.hasReceivedMemoryWarningInLastSession
Примечание
Этот метод следует использовать только после Crashes
запуска, он всегда будет возвращать NO
или false
перед запуском.
Примечание
В некоторых случаях устройство с нехваткой памяти не может отправлять события.
В любой момент после запуска пакета SDK можно проверка, если приложение аварийно завершалось при предыдущем запуске:
[MSACCrashes hasCrashedInLastSession];
Crashes.hasCrashedInLastSession
Это удобно в случае, если вы хотите настроить поведение или пользовательский интерфейс приложения после сбоя.
Примечание
Этот метод следует использовать только после MSACCrashes
запуска, он всегда будет возвращать NO
или false
перед запуском.
Если приложение ранее завершалось сбоем, вы можете получить сведения о последнем сбое.
MSACErrorReport *crashReport = [MSACCrashes lastSessionCrashReport];
var crashReport = Crashes.lastSessionCrashReport
Примечание
Этот метод следует использовать только после Crashes
запуска. Он всегда возвращается nil
перед запуском.
Существует множество вариантов использования этого API. Наиболее распространенные из них — люди, которые вызывают этот API и реализуют свои пользовательские CrashesDelegate.
Сбои Центра приложений предоставляют разработчикам обратные вызовы для выполнения дополнительных действий до и при отправке журналов сбоев в Центр приложений.
Чтобы добавить пользовательское поведение, необходимо внедрить CrashesDelegate
протокол -protocol, все его методы являются необязательными.
[MSACCrashes setDelegate:self];
Crashes.delegate = self
Примечание
Необходимо задать делегат перед вызовом AppCenter.start
, так как центр приложений запускает обработку сразу после запуска.
crashes:shouldProcessErrorReport:
Реализуйте -method в классе , который принимает CrashesDelegate
протокол , если вы хотите решить, нужно ли обрабатывать конкретный сбой. Например, может произойти сбой на уровне системы, который вы хотите игнорировать и не хотите отправлять в Центр приложений.
- (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.
}
Центр приложений также позволяет отслеживать ошибки с помощью обработанного исключения с помощью trackError
метода . При необходимости приложение может вложить свойства или (и) вложения в отчет об ошибках, обрабатываемый для предоставления дополнительного контекста.
@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)
}
Для отслеживания исключений можно использовать 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)
}
Если конфиденциальность пользователей важна для вас, вы можете получить подтверждение пользователей перед отправкой отчета о сбоях в Центр приложений. Пакет SDK предоставляет обратный вызов, который сообщает о сбоях Центра приложений о том, что перед отправкой отчетов о сбоях ожидается подтверждение пользователей.
Если вы решили сделать это, вы несете ответственность за получение подтверждения пользователя, например с помощью диалогового окна с одним из следующих вариантов: Всегда отправлять, Отправлять и Не отправлять. На основе входных данных вы сообщите Центру приложений, что делать, и сбой будет обрабатываться соответствующим образом.
Примечание
Пакет SDK не отображает диалоговое окно для этого, приложение должно предоставить собственный пользовательский интерфейс для запроса согласия пользователя.
Примечание
Приложение не должно вызывать notifyWithUserConfirmation
явным образом, если оно не реализует диалоговое окно подтверждения пользователя; модуль Аварийное завершение будет обрабатывать отправку журналов для вас неявно.
В следующем методе показано, как настроить обработчик подтверждения пользователя:
[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.
})];
MSACCrashes.setUserConfirmationHandler({ (errorReports: [MSACErrorReport]) 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
MSACCrashes.notify(with: .dontSend)
})
alertController.addAction(UIAlertAction(title: "Send", style: .default) {_ in
MSACCrashes.notify(with: .send)
})
alertController.addAction(UIAlertAction(title: "Always send", style: .default) {_ in
MSACCrashes.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.
})
Если вы вернелись YES
/true
к приведенному выше блоку обработчика, приложение должно получить разрешение пользователя и предоставить пакет SDK с результатом, используя следующий API. Если вы используете для этого оповещение, как в приведенном выше примере, вы можете вызвать его из реализации обратного alertView:clickedButtonAtIndex:
вызова -.
// 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.
MSACCrashes.notify(with: .dontSend)
MSACCrashes.notify(with: .send)
MSACCrashes.notify(with: .always)
Иногда требуется узнать состояние сбоя приложения. Распространенный вариант использования заключается в том, что может потребоваться показать пользовательский интерфейс, который сообщает пользователям, что приложение отправляет отчет о сбоях, или, если приложение быстро аварийно завершает работу после запуска, необходимо настроить поведение приложения, чтобы убедиться, что журналы сбоев можно отправить. Протокол CrashesDelegate
-определяет три разных обратных вызова, которые можно использовать в приложении для получения уведомлений о том, что происходит:
- (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.
}
Если у нас есть проблемы с сетью или сбой в конечной точке, и вы перезапустите приложение, willSendErrorReport
активируется снова после перезапуска процесса.
- (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.
}
Получение didFailSendingErrorReport
означает, что произошла невосстановимая ошибка, например код 4xx . Например, 401 означает, что appSecret
неправильно.
Этот обратный вызов не активируется, если это проблема с сетью. В этом случае пакет SDK продолжает повторять попытки (а также приостанавливает повторные попытки, пока сетевое подключение не работает).
В отчет о сбое можно добавлять двоичные и текстовые вложения. Пакет SDK отправит их вместе со сбоем, чтобы их можно было увидеть на портале Центра приложений. Следующий обратный вызов будет вызван непосредственно перед отправкой сохраненного сбоя из предыдущих запусков приложения. Он не будет вызываться при сбое. Ниже приведен пример вложения текста и изображения в сбой:
- (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!]
}
Примечание
В настоящее время максимальный размер составляет 7 МБ. Попытка отправить вложение большего размера вызовет ошибку.
Вы можете включить и отключить сбои Центра приложений во время выполнения. Если вы отключите его, пакет SDK не будет сообщать о сбоях для приложения.
[MSACCrashes setEnabled:NO];
Crashes.enabled = false
Чтобы снова включить сбои центра приложений, используйте тот же API, но передайте YES
/true
в качестве параметра.
[MSACCrashes setEnabled:YES];
Crashes.enabled = true
Состояние сохраняется в хранилище устройства при запуске приложений.
Примечание
Этот метод следует использовать только после Crashes
запуска.
Вы также можете проверка, включены ли сбои Центра приложений:
BOOL enabled = [MSACCrashes isEnabled];
var enabled = Crashes.enabled
Примечание
Этот метод следует использовать только после Crashes
запуска. Он всегда возвращается false
перед запуском.