Сбои центра приложений (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-определяет три разных обратных вызова, которые можно использовать в приложении для получения уведомлений о том, что происходит:

Следующий обратный вызов будет вызван до того, как пакет 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.
}

Если у нас есть проблемы с сетью или сбой в конечной точке, и вы перезапустите приложение, willSendErrorReport активируется снова после перезапуска процесса.

Следующий обратный вызов будет вызван после успешной отправки пакета 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.
}

Следующий обратный вызов будет вызываться, если пакету SDK не удалось отправить журнал сбоев

- (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 перед запуском.