共用方式為


App Center 崩潰 (tvOS)

這很重要

Visual Studio App Center 於 2025 年 3 月 31 日淘汰,但分析和診斷功能除外,這些功能將持續支援到 2026 年 6 月 30 日。 瞭解更多資訊。

App Center 崩潰會在每次應用程式當機時自動產生當機記錄檔。 記錄會先寫入裝置的記憶體,當使用者再次啟動應用程式時,當機報告會傳送至 App Center。 收集崩潰資訊適用於 Beta 和上線的應用程式,也就是已提交到 App Store 的應用程式。 當機記錄包含協助您修正當機的重要資訊。

如果您尚未在應用程式中設定 SDK,請遵循 開始使用 一節。

此外,tvOS 上的當機記錄需要符號,請參閱 App Center 診斷檔 ,說明如何為您的應用程式提供符號。

備註

若要接收正確符號化的堆疊追蹤,請確定已停用 bitcode。 您可以在 App Center 的 iOS 符號檔中深入瞭解 bitcode。

備註

4.0.0 App Center 重大變更版本中引進。 遵循 移轉至 App Center SDK 4.0.0 和更新 版本一節,從舊版移轉 App Center。

產生測試當機

App Center 當機提供 API 來產生測試當機,以便輕鬆測試 SDK。 此 API 只能用於測試/Beta 應用程式,且不會在生產應用程式中執行任何動作。

[MSACCrashes generateTestCrash];
Crashes.generateTestCrash()

取得先前當機的詳細資訊

App Center Crashes 有兩個 API,可以在應用程式當機時提供更多資訊。

應用程式在上一個會話中是否收到記憶體不足的警告?

在啟動 SDK 之後,您可以隨時檢查應用程式是否在上一個工作階段中收到記憶體警告:

[MSACCrashes hasReceivedMemoryWarningInLastSession];
Crashes.hasReceivedMemoryWarningInLastSession

備註

此方法只能在 Crashes 啟動後使用,在啟動之前,它總是會回傳 NOfalse

備註

在某些情況下,記憶體不足的裝置無法傳送事件。

應用程式在上一個工作階段中是否當機?

在啟動 SDK 之後,您可以隨時檢查應用程式是否在上一次啟動中當機:

[MSACCrashes hasCrashedInLastSession];
Crashes.hasCrashedInLastSession

如果您想要在發生當機后調整應用程式的行為或 UI,這會派上用場。

備註

此方法只能在 MSACCrashes 啟動後使用,在啟動之前,它總是會回傳 NOfalse

上次當機的詳細數據

如果您的應用程式先前當機,您可以取得上次當機的詳細數據。

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

備註

這個方法只能在 Crashes 已啟動後使用,開始之前它總是會傳回 nil

此 API 有許多使用案例,最常見的使用案例是呼叫此 API 並實作其自定義 CrashesDelegate 的人員。

自訂 App Center 當機的使用方式

App Center 當機提供回呼,讓開發人員在將損毀記錄傳送至 App Center 之前和時執行其他動作。

若要新增自定義行為,您必須採用 CrashesDelegate-protocol,其所有方法都是選擇性的。

註冊為代表

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

備註

您必須在呼叫 之前設定 AppCenter.start,因為 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 損毀要執行的動作,然後會據以處理損毀。

備註

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 與結果。 如果您使用此警示,如上述範例所示,您會從 -callback 的 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,告知使用者您的應用程式正在提交當機報告,或者,如果app在啟動後快速當機,您想要調整應用程式的行為,以確保可以提交當機記錄。 CrashesDelegate-protocol 會定義三個不同的回呼,您可以在應用程式中用來收到發生狀況的通知:

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 損毀是否已啟用:

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

備註

這個方法只能在 Crashes 已啟動後使用,開始之前它總是會傳回 false