次の方法で共有


App Center のクラッシュ (tvOS)

重要

Visual Studio App Center は、2026 年 6 月 30 日まで引き続きサポートされる分析機能と診断機能を除き、2025 年 3 月 31 日に廃止されました。 詳細を参照してください。

App Center のクラッシュでは、アプリがクラッシュするたびにクラッシュ ログが自動的に生成されます。 ログは最初にデバイスのストレージに書き込まれ、ユーザーがアプリを再度起動すると、クラッシュ レポートが App Center に送信されます。 クラッシュの収集は、ベータ版アプリとライブ アプリ (App Store に送信されたアプリ) の両方で機能します。 クラッシュ ログには、クラッシュの修正に役立つ貴重な情報が含まれています。

アプリケーションで SDK をまだ設定していない場合は、「 はじめ に」セクションに従います。

また、tvOS のクラッシュ ログにはシンボリック化が必要です。アプリのシンボルを提供する方法については、 App Center Diagnostics のドキュメント を参照してください。

適切にシンボル化されたスタック トレースを受信するには、ビットコードが無効になっていることを確認します。 ビットコードの詳細については、App Center の iOS シンボリック化に関するドキュメントを参照してください

4.0.0 バージョンの App Center では、破壊的変更が導入されました。 App Center SDK 4.0.0 以降に移行するセクションに従って、App Center を以前のバージョンから移行します。

テスト クラッシュを生成する

App Center のクラッシュには、SDK を簡単にテストするためのテスト クラッシュを生成する API が用意されています。 この API はテスト/ベータ アプリでのみ使用でき、運用アプリでは何も行いません。

[MSACCrashes generateTestCrash];
Crashes.generateTestCrash()

以前のクラッシュに関する詳細情報を取得する

App Center のクラッシュには、アプリがクラッシュした場合に備えて詳細情報を提供する 2 つの API があります。

アプリは前のセッションでメモリ不足の警告を受け取りましたか?

SDK を起動した後は、前のセッションでアプリがメモリ警告を受信したかどうかをいつでも確認できます。

[MSACCrashes hasReceivedMemoryWarningInLastSession];
Crashes.hasReceivedMemoryWarningInLastSession

このメソッドは、 Crashes が開始された後にのみ使用する必要があり、常に開始前に NO または false を返します。

メモリが不足しているデバイスでイベントを送信できない場合があります。

前のセッションでアプリがクラッシュしましたか?

SDK を起動した後は、前回の起動時にアプリがクラッシュしたかどうかをいつでも確認できます。

[MSACCrashes hasCrashedInLastSession];
Crashes.hasCrashedInLastSession

これは、クラッシュが発生した後にアプリの動作または UI を調整する場合に便利です。

このメソッドは、 MSACCrashes が開始された後にのみ使用する必要があり、常に開始前に NO または false を返します。

前回のクラッシュの詳細

アプリが以前にクラッシュした場合は、最後のクラッシュに関する詳細を取得できます。

MSACErrorReport *crashReport = [MSACCrashes lastSessionCrashReport];
var crashReport = Crashes.lastSessionCrashReport

このメソッドは、 Crashes が開始された後にのみ使用する必要があり、常に開始前に nil 返されます。

この API には多くのユース ケースがあります。最も一般的なのは、この API を呼び出し、カスタム の CrashesDelegate を実装するユーザーです。

App Center のクラッシュ機能の使い方をカスタマイズする

App Center のクラッシュは、クラッシュ ログを App Center に送信する前と送信する際に、開発者が追加のアクションを実行するためのコールバックを提供します。

カスタム動作を追加するには、 CrashesDelegate プロトコルを採用する必要があります。そのメソッドはすべて省略可能です。

代理人として登録する

[MSACCrashes setDelegate:self];
Crashes.delegate = self

App Center が起動するとすぐにクラッシュの処理を始めるため、を呼び出す前にデリゲートを設定しておく必要があります。

クラッシュを処理する必要がありますか?

特定のクラッシュを処理する必要があるかどうかを判断する場合は、crashes:shouldProcessErrorReport:プロトコルを採用するクラスにCrashesDelegateメソッドを実装します。 たとえば、無視して 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 では、 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)
}

ユーザーのプライバシーが重要な場合は、クラッシュ レポートを App Center に送信する前に、ユーザーの確認を取得することをお勧めします。 SDK は、クラッシュ レポートを送信する前にユーザーの確認を待つよう App Center のクラッシュに指示するコールバックを公開します。

これを選択した場合は、ユーザーの確認を取得する必要があります。たとえば、ダイアログ プロンプトで次のいずれかのオプションを使用します。 常に送信送信送信しない。 入力に基づいて、App Center Crashes に指示を与えることで、そのクラッシュが適切に処理されます。

SDK にはこれに対するダイアログは表示されません。アプリは、ユーザーの同意を求めるために独自の UI を提供する必要があります。

ユーザー確認ダイアログが実装されていない場合、アプリは 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 を返した場合、アプリはユーザーのアクセス許可を取得し、次の API を使用して結果を SDK にメッセージする必要があります。 上記のサンプルのように、これに対してアラートを使用している場合は、 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)

クラッシュ ログの送信状態に関する情報を取得する

場合によっては、アプリのクラッシュの状態を知りたい場合があります。 一般的なユース ケースは、アプリがクラッシュ レポートを送信していることをユーザーに通知する UI を表示する場合や、起動後にアプリがすぐにクラッシュする場合は、クラッシュ ログを送信できるようにアプリの動作を調整する必要がある場合です。 CrashesDelegate プロトコルでは、アプリで何が起こっているかを通知するために使用できる 3 つの異なるコールバックが定義されています。

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 はクラッシュと共にそれらのデータを送信し、App Center ポータルで表示できるようになります。 次のコールバックは、以前のアプリケーションの起動から格納されたクラッシュを送信する直前に呼び出されます。 クラッシュが発生しても呼び出されません。 クラッシュにテキストと画像を添付する方法の例を次に示します。

- (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 MB です。 大きな添付ファイルを送信しようとすると、エラーが発生します。

実行時に App Center のクラッシュを有効または無効にする

実行時に App Center のクラッシュを有効または無効にすることができます。 無効にした場合、SDK はアプリのクラッシュ レポートを実行しません。

[MSACCrashes setEnabled:NO];
Crashes.enabled = false

App Center のクラッシュを再度有効にするには、同じ API を使用しますが、パラメーターとして YES/true を渡します。

[MSACCrashes setEnabled:YES];
Crashes.enabled = true

状態は、アプリケーションの起動間でデバイスのストレージに保持されます。

このメソッドは、 Crashes が開始された後にのみ使用する必要があります。

App Center のクラッシュ機能が有効になっているかどうかを確認する

App Center Crashes 機能が有効になっているかどうかを確認することもできます。

BOOL enabled = [MSACCrashes isEnabled];
var enabled = Crashes.enabled

このメソッドは、 Crashes が開始された後にのみ使用する必要があり、常に開始前に false 返されます。