App Center Crash (macOS)
Penting
Visual Studio App Center dijadwalkan untuk dihentikan pada 31 Maret 2025. Meskipun Anda dapat terus menggunakan Visual Studio App Center hingga sepenuhnya dihentikan, ada beberapa alternatif yang direkomendasikan yang dapat Anda pertimbangkan untuk bermigrasi.
Pelajari selengkapnya tentang garis waktu dukungan dan alternatif.
App Center Crash akan secara otomatis menghasilkan log crash setiap kali aplikasi Anda crash. Log pertama kali ditulis ke penyimpanan perangkat dan ketika pengguna memulai aplikasi lagi, laporan crash akan dikirim ke App Center. Mengumpulkan crash berfungsi untuk aplikasi beta dan live, yaitu yang dikirimkan ke App Store. Log crash berisi informasi berharga bagi Anda untuk membantu memperbaiki crash.
Ikuti bagian Memulai jika Anda belum menyiapkan SDK di aplikasi Anda.
Selain itu, log crash di macOS memerlukan Simbolikasi, lihat dokumentasi Diagnostik App Center yang menjelaskan cara menyediakan simbol untuk aplikasi Anda.
Catatan
4.0.0
Dalam versi perubahan pemecahan App Center diperkenalkan. Ikuti bagian Migrasi ke App Center SDK 4.0.0 dan yang lebih tinggi untuk memigrasikan App Center dari versi sebelumnya.
App Center mendukung pelaporan crash di ekstensi macOS. Penggunaannya sama seperti dalam aplikasi kontainer.
App Center Crashes memberi Anda API untuk menghasilkan crash pengujian agar mudah menguji SDK. API ini hanya dapat digunakan dalam aplikasi pengujian/beta dan tidak akan melakukan apa pun di aplikasi produksi.
[MSACCrashes generateTestCrash];
Crashes.generateTestCrash()
App Center Crashes memiliki dua API yang memberi Anda informasi lebih lanjut jika aplikasi Anda mengalami crash.
Kapan saja setelah memulai SDK, Anda dapat memeriksa apakah aplikasi menerima peringatan memori di sesi sebelumnya:
[MSACCrashes hasReceivedMemoryWarningInLastSession];
Crashes.hasReceivedMemoryWarningInLastSession
Catatan
Metode ini hanya boleh digunakan setelah Crashes
dimulai, metode ini akan selalu kembali NO
atau false
sebelum dimulai.
Catatan
Dalam beberapa kasus, perangkat dengan memori rendah tidak dapat mengirim peristiwa.
Kapan saja setelah memulai SDK, Anda dapat memeriksa apakah aplikasi mengalami crash di peluncuran sebelumnya:
[MSACCrashes hasCrashedInLastSession];
Crashes.hasCrashedInLastSession
Ini berguna jika Anda ingin menyesuaikan perilaku atau UI aplikasi Anda setelah crash terjadi.
Catatan
Metode ini hanya boleh digunakan setelah MSACCrashes
dimulai, metode ini akan selalu kembali NO
atau false
sebelum dimulai.
Jika aplikasi Anda mengalami crash sebelumnya, Anda bisa mendapatkan detail tentang crash terakhir.
MSACErrorReport *crashReport = [MSACCrashes lastSessionCrashReport];
var crashReport = Crashes.lastSessionCrashReport
Catatan
Metode ini hanya boleh digunakan setelah Crashes
dimulai, metode ini akan selalu kembali nil
sebelum dimulai.
Ada banyak kasus penggunaan untuk API ini, yang paling umum adalah orang-orang yang memanggil API ini dan menerapkan CrashesDelegate kustom mereka.
App Center Crash menyediakan panggilan balik bagi pengembang untuk melakukan tindakan tambahan sebelum dan saat mengirim log crash ke App Center.
Untuk menambahkan perilaku kustom, Anda perlu mengadopsi CrashesDelegate
-protokol, semua metodenya bersifat opsional.
[MSACCrashes setDelegate:self];
Crashes.delegate = self
Catatan
Anda harus mengatur delegasi sebelum memanggil AppCenter.start
, karena App Center mulai memproses crash segera setelah mulai.
Terapkan crashes:shouldProcessErrorReport:
-method di kelas yang mengadopsi -protocol jika Anda ingin memutuskan apakah crash tertentu perlu diproses CrashesDelegate
atau tidak. Misalnya, mungkin ada crash tingkat sistem yang ingin Anda abaikan dan yang tidak ingin Anda kirim ke 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 juga memungkinkan Anda melacak kesalahan dengan menggunakan pengecualian yang ditangani melalui trackError
metode . Aplikasi dapat secara opsional melampirkan properti atau/dan lampiran ke laporan kesalahan yang ditangani untuk memberikan konteks lebih lanjut.
@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)
}
Untuk pengecualian trek, Anda dapat menggunakan trackException
metode :
@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)
}
Jika privasi pengguna penting bagi Anda, Anda mungkin ingin mendapatkan konfirmasi pengguna sebelum mengirim laporan crash ke App Center. SDK memaparkan panggilan balik yang memberi tahu App Center Crash untuk menunggu konfirmasi pengguna sebelum mengirim laporan crash.
Jika Anda memilih untuk melakukannya, Anda bertanggung jawab untuk mendapatkan konfirmasi pengguna, misalnya melalui perintah dialog dengan salah satu opsi berikut: Selalu kirim, Kirim, dan Jangan kirim. Berdasarkan input, Anda akan memberi tahu App Center Crash apa yang harus dilakukan dan crash kemudian akan ditangani dengan sesuai.
Catatan
SDK tidak menampilkan dialog untuk ini, aplikasi harus menyediakan UI sendiri untuk meminta persetujuan pengguna.
Metode berikut menunjukkan cara menyiapkan penangan konfirmasi pengguna:
[MSACCrashes setUserConfirmationHandler:(^(NSArray<MSACErrorReport *> *errorReports) {
// Your code to present your UI to the user, e.g. an NSAlert.
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:@"Sorry about that!"];
[alert setInformativeText:@"Do you want to send an anonymous crash report so we can fix the issue?"];
[alert addButtonWithTitle:@"Always send"];
[alert addButtonWithTitle:@"Send"];
[alert addButtonWithTitle:@"Don't send"];
[alert setAlertStyle:NSWarningAlertStyle];
switch ([alert runModal]) {
case NSAlertFirstButtonReturn:
[MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationAlways];
break;
case NSAlertSecondButtonReturn:
[MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationSend];
break;
case NSAlertThirdButtonReturn:
[MSACCrashes notifyWithUserConfirmation:MSACUserConfirmationDontSend];
break;
default:
break;
}
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 NSAlert.
let alert: NSAlert = NSAlert()
alert.messageText = "Sorry about that!"
alert.informativeText = "Do you want to send an anonymous crash report so we can fix the issue?"
alert.addButton(withTitle: "Always send")
alert.addButton(withTitle: "Send")
alert.addButton(withTitle: "Don't send")
alert.alertStyle = NSWarningAlertStyle
switch (alert.runModal()) {
case NSAlertFirstButtonReturn:
Crashes.notify(with: .always)
break;
case NSAlertSecondButtonReturn:
Crashes.notify(with: .send)
break;
case NSAlertThirdButtonReturn:
Crashes.notify(with: .dontSend)
break;
default:
break;
}
return true // Return true if the SDK should await user confirmation, otherwise return false.
})
Jika Anda kembali YES
/true
di blok handler di atas, aplikasi Anda harus mendapatkan izin pengguna dan mengirim pesan ke SDK dengan hasilnya menggunakan API berikut. Jika Anda menggunakan pemberitahuan untuk ini, seperti yang kami lakukan dalam sampel di atas, Anda akan memanggilnya berdasarkan hasil panggilan (ModalResponse).runModal
// Depending on the user'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)
AppKit menangkap pengecualian yang dilemparkan pada utas utama, mencegah aplikasi crash di macOS, sehingga SDK tidak dapat menangkap crash ini. Untuk meniru perilaku iOS, atur NSApplicationCrashOnExceptions
bendera sebelum inisialisasi SDK, bendera ini memungkinkan aplikasi crash pada pengecualian yang tidak tertangkap dan SDK dapat melaporkannya.
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"NSApplicationCrashOnExceptions" : @YES }];
UserDefaults.standard.register(defaults: ["NSApplicationCrashOnExceptions": true])
Catatan
App Center SDK mengatur bendera secara otomatis di versi 1.10.0 ke bawah. Dimulai dengan versi 1.11.0, bendera ini tidak lagi diatur secara otomatis.
App Center Crashes SDK menggunakan swizzling untuk meningkatkan integrasinya dengan meneruskan sendiri beberapa panggilan metode kelas utama aplikasi. Metode menggeser adalah cara untuk mengubah implementasi metode pada runtime. Jika karena alasan apa pun Anda tidak ingin menggunakan denyut (misalnya karena kebijakan tertentu), Anda harus mengambil alih aplikasi reportException:
dan sendEvent:
metode sendiri agar Crash melaporkan pengecualian yang dilemparkan pada utas utama dengan benar.
Buat file ReportExceptionApplication.m dan tambahkan implementasi berikut:
@import Cocoa; @import AppCenterCrashes; @interface ReportExceptionApplication : NSApplication @end @implementation ReportExceptionApplication - (void)reportException:(NSException *)exception { [MSACCrashes applicationDidReportException:exception]; [super reportException:exception]; } - (void)sendEvent:(NSEvent *)theEvent { @try { [super sendEvent:theEvent]; } @catch (NSException *exception) { [self reportException:exception]; } } @end
Catatan
Swift tidak
try
/catch
berfungsi dengan .NSException
Pengecualian ini hanya dapat ditangani di Objective-C.Buka file Info.plist dan ganti NSApplication di bidang Kelas utama dengan nama kelas aplikasi Anda, ReportExceptionApplication dalam contoh ini.
Untuk menonaktifkan swizzling di App Center SDK, tambahkan
AppCenterApplicationForwarderEnabled
kunci ke file Info.plist , dan atur nilainya ke0
.
Terkadang, Anda ingin mengetahui status crash aplikasi Anda. Kasus penggunaan umum adalah Anda mungkin ingin menampilkan UI yang memberi tahu pengguna bahwa aplikasi Anda mengirimkan laporan crash, atau, jika aplikasi Anda crash dengan cepat setelah peluncuran, Anda ingin menyesuaikan perilaku aplikasi untuk memastikan log crash dapat dikirimkan. CrashesDelegate
-protocol mendefinisikan tiga panggilan balik berbeda yang dapat Anda gunakan di aplikasi Anda untuk diberi tahu tentang apa yang terjadi:
- (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.
}
Jika kami mengalami masalah jaringan atau pemadaman pada titik akhir, dan Anda memulai ulang aplikasi, willSendErrorReport
dipicu lagi setelah proses dimulai ulang.
- (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.
}
Penerimaan didFailSendingErrorReport
berarti terjadi kesalahan yang tidak dapat dipulihkan seperti kode 4xx . Misalnya, 401 berarti appSecret
salah.
Panggilan balik ini tidak dipicu jika masalah jaringan. Dalam hal ini, SDK terus mencoba kembali (dan juga menjeda percobaan kembali saat koneksi jaringan tidak berfungsi).
Anda dapat menambahkan lampiran biner dan teks ke laporan crash. SDK akan mengirimkannya bersama dengan crash sehingga Anda dapat melihatnya di portal App Center. Panggilan balik berikut akan dipanggil tepat sebelum mengirim crash yang disimpan dari peluncuran aplikasi sebelumnya. Ini tidak akan dipanggil ketika crash terjadi. Berikut adalah contoh cara melampirkan teks dan gambar ke crash:
- (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!]
}
Catatan
Batas ukuran saat ini adalah 7 MB. Mencoba mengirim lampiran yang lebih besar akan memicu kesalahan.
Anda dapat mengaktifkan dan menonaktifkan App Center Crash saat runtime. Jika Anda menonaktifkannya, SDK tidak akan melakukan pelaporan crash untuk aplikasi.
[MSACCrashes setEnabled:NO];
Crashes.enabled = false
Untuk mengaktifkan App Center Crash lagi, gunakan API yang sama tetapi lewati YES
/true
sebagai parameter.
[MSACCrashes setEnabled:YES];
Crashes.enabled = true
Status ini bertahan di penyimpanan perangkat di seluruh peluncuran aplikasi.
Catatan
Metode ini hanya boleh digunakan setelah Crashes
dimulai.
Anda juga dapat memeriksa apakah App Center Crash diaktifkan atau tidak:
BOOL enabled = [MSACCrashes isEnabled];
var enabled = Crashes.enabled
Catatan
Metode ini hanya boleh digunakan setelah Crashes
dimulai, metode ini akan selalu kembali false
sebelum dimulai.
Secara default, App Center Crash menggunakan handler pengecualian Mach untuk menangkap sinyal fatal, misalnya luapan tumpukan, melalui server pengecualian Mach.
- disableMachExceptionHandler
method menyediakan opsi untuk menonaktifkan penangkapan sinyal fatal melalui server pengecualian Mach. Jika Anda ingin menonaktifkan handler pengecualian Mach, Anda harus memanggil metode ini SEBELUM memulai SDK. Kode penyiapan khas Anda akan terlihat seperti ini:
[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])