IOS) 的 App Center 損毀 (

App Center 損毀會在每次應用程式損毀時自動產生損毀記錄檔。 記錄檔會先寫入裝置的儲存體,當使用者再次啟動應用程式時,會將損毀報告傳送至 App Center。 收集和即時應用程式(也就是提交給 App Store 的應用程式)的收集損毀運作。 損毀記錄檔包含可協助您修正損毀的重要資訊。

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

此外,iOS 上的損毀記錄檔需要符號化,請參閱說明如何為您的應用程式提供符號的 App Center 診斷檔

注意

如果您附加至偵錯工具,SDK 將無法轉寄任何損毀記錄檔。 當您損毀應用程式時,請確定未附加偵錯工具。

注意

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

注意

引進了 4.0.0 App Center 中斷變更的版本。 遵循 [ 遷移至 App CENTER SDK 4.0.0 和 更新版本] 區段,從舊版遷移 App center。

延伸模組中的損毀報告

App Center 支援 iOS 延伸模組中的當機報告。 使用方式與容器應用程式中的使用方式相同。

產生測試損毀

App Center 損毀提供您 API 來產生測試損毀,以便輕鬆地測試 SDK。 此 API 僅適用于測試/Beta 應用程式,且不會在生產應用程式中執行任何動作。

[MSACCrashes generateTestCrash];
Crashes.generateTestCrash()

取得有關先前損毀的詳細資訊

App Center 損毀有兩個 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 -通訊協定,其所有方法都是選擇性的。

註冊為委派

[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.
})];
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.
})

如果您在 YES / true 上述的處理常式區塊中返回,您的應用程式應該會取得使用者權限,並使用下列 API 以結果將 SDK 訊息給 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.
Crashes.notify(with: .dontSend)
Crashes.notify(with: .send)
Crashes.notify(with: .always)

取得損毀記錄檔的傳送狀態相關資訊

有時,您會想要知道應用程式損毀的狀態。 常見的使用案例是,您可能會想要顯示 UI,告訴使用者您的應用程式正在提交損毀報告,或者,如果您的應用程式在啟動後快速當機,則您想要調整應用程式的行為,以確保可以提交損毀記錄。 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 會將它們連同損毀一起傳送,讓您可以在 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 損毀:

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

注意

只有在啟動之後,才會使用這個方法 Crashes ,在開始之前,它一定會傳回 false

停用符合例外狀況處理

根據預設,App Center 損毀會使用符合例外狀況處理常式,透過符合例外狀況伺服器攔截嚴重信號,例如堆疊溢位。

disableMachExceptionHandler-方法提供一個選項,可停用透過符合例外狀況伺服器攔截的嚴重信號。 如果您想要停用符合例外狀況處理常式,您應該在啟動 SDK 之前 呼叫這個方法。 一般的安裝程式碼看起來像這樣:

[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])