Aracılığıyla paylaş


App Center Kilitlenmeleri (macOS)

Önemli

Visual Studio App Center 31 Mart 2025'te kullanımdan kaldırılıyor. Tamamen kullanımdan kaldırılana kadar Visual Studio App Center'ı kullanmaya devam edebilirsiniz ancak geçiş yapmayı düşünebileceğiniz birkaç önerilen alternatif vardır.

Destek zaman çizelgeleri ve alternatifleri hakkında daha fazla bilgi edinin.

App Center Kilitlenmeleri, uygulamanız her kilitlenişinde otomatik olarak bir kilitlenme günlüğü oluşturur. Günlük ilk olarak cihazın depolama alanına yazılır ve kullanıcı uygulamayı yeniden başlattığında kilitlenme raporu App Center'a gönderilir. Kilitlenmeleri toplamak hem beta hem de canlı uygulamalarda(App Store gönderilenler) çalışır. Kilitlenme günlükleri, kilitlenmeyi düzeltmenize yardımcı olacak değerli bilgiler içerir.

Uygulamanızda SDK'yı henüz ayarlamadıysanız Başlarken bölümünü izleyin.

Ayrıca, macOS'ta kilitlenme günlükleri Sembolikleştirme gerektirir. Uygulamanız için sembollerin nasıl sağlandığını açıklayan App Center Tanılama belgelerine göz atın.

Not

4.0.0 App Center sürümünde hataya neden olan değişiklikler kullanıma sunulmuştur. App Center'ı önceki sürümlerden geçirmek için App Center SDK 4.0.0 ve üzeri sürümlere geçiş bölümünü izleyin.

Uzantılarda kilitlenme raporlaması

App Center, macOS uzantılarında kilitlenme raporlamayı destekler. Kullanım, kapsayıcı uygulamasındakiyle aynıdır.

Test kilitlenmesi oluşturma

App Center Kilitlenmeleri, SDK'nın kolay test edilmesi için bir test kilitlenmesi oluşturmanızı sağlayan bir API sağlar. Bu API yalnızca test/beta uygulamalarında kullanılabilir ve üretim uygulamalarında hiçbir şey yapmaz.

[MSACCrashes generateTestCrash];
Crashes.generateTestCrash()

Önceki kilitlenme hakkında daha fazla bilgi edinin

App Center Kilitlenmeleri, uygulamanızın kilitlenmesi durumunda size daha fazla bilgi sağlayan iki API'ye sahiptir.

Uygulama önceki oturumda düşük bellek uyarısı mı aldı?

SDK'yı başlattıktan sonra, uygulamanın önceki oturumda bir bellek uyarısı aldığından istediğiniz zaman kontrol edebilirsiniz:

[MSACCrashes hasReceivedMemoryWarningInLastSession];
Crashes.hasReceivedMemoryWarningInLastSession

Not

Bu yöntem yalnızca başlatıldıktan sonra Crashes kullanılmalıdır, her zaman veya false başlamadan önce döndürülecektirNO.

Not

Bazı durumlarda, belleği düşük olan bir cihaz olayları gönderemez.

Uygulama önceki oturumda kilitleniyor muydu?

SDK'yı başlattıktan sonra, uygulamanın önceki başlatmada kilitlenip kilitlenmediğini kontrol edebilirsiniz:

[MSACCrashes hasCrashedInLastSession];
Crashes.hasCrashedInLastSession

Bu, kilitlenme gerçekleştikten sonra uygulamanızın davranışını veya kullanıcı arabirimini ayarlamak istemeniz durumunda kullanışlıdır.

Not

Bu yöntem yalnızca başlatıldıktan sonra MSACCrashes kullanılmalıdır, her zaman veya false başlamadan önce döndürülecektirNO.

Son kilitlenmeyle ilgili ayrıntılar

Uygulamanız daha önce kilitlendiyse son kilitlenmeyle ilgili ayrıntıları alabilirsiniz.

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

Not

Bu yöntem yalnızca başlatıldıktan sonra Crashes kullanılmalıdır; her zaman başlamadan önce döndürülecektir nil .

Bu API için çok sayıda kullanım örneği vardır ve en yaygın olanı bu API'yi çağıran ve özel CrashesDelegate'lerini uygulayan kişilerdir.

App Center Kilitlenmeleri kullanımınızı özelleştirme

App Center Kilitlenmeleri, geliştiricilerin App Center'a kilitlenme günlükleri göndermeden önce ve gönderirken ek eylemler gerçekleştirmesi için geri çağırmalar sağlar.

Özel davranışınızı eklemek için - protokolünü CrashesDelegatebenimsemeniz gerekir, tüm yöntemleri isteğe bağlıdır.

Temsilci olarak kaydetme

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

Not

App Center başlatmadan hemen sonra kilitlenmeleri işlemeye başladığından, çağırmadanAppCenter.startönce temsilciyi ayarlamanız gerekir.

Kilitlenme işlenmeli mi?

Belirli bir kilitlenmenin crashes:shouldProcessErrorReport:işlenmesi gerekip gerekmediğine karar vermek istiyorsanız -protocol'u benimseyen CrashesDelegatesınıfta -method'u uygulayın. Örneğin, yoksaymak istediğiniz ve App Center'a göndermek istemediğiniz bir sistem düzeyinde kilitlenme olabilir.

- (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.
}

İşlenen Hatalar

App Center ayrıca yöntem aracılığıyla trackError işlenen özel durumları kullanarak hataları izlemenize de olanak tanır. Bir uygulama isteğe bağlı olarak, daha fazla bağlam sağlamak için işlenen hata raporuna özellikler veya/ve ekler ekleyebilir.

@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)
}

İzleme özel durumları için yöntemini kullanabilirsiniz 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)
}

Kullanıcı gizliliği sizin için önemliyse, App Center'a kilitlenme raporu göndermeden önce kullanıcı onayı almak isteyebilirsiniz. SDK, App Center Kilitlenmeleri'ne herhangi bir kilitlenme raporu göndermeden önce kullanıcı onayını beklemesini bildiren bir geri çağırma sunar.

Bunu yapmayı seçerseniz, kullanıcının onayını almak sizin sorumluluğundadır; örneğin, aşağıdaki seçeneklerden birini içeren bir iletişim kutusu istemi aracılığıyla: Her zaman gönder, Gönder ve Gönderme. Girişe bağlı olarak App Center Crashes'e ne yapması gerektiğini söyleyeceksiniz ve kilitlenme buna göre işlenir.

Not

SDK bunun için bir iletişim kutusu görüntülemez, uygulamanın kullanıcı onayı istemek için kendi kullanıcı arabirimini sağlaması gerekir.

Aşağıdaki yöntem, kullanıcı onay işleyicisinin nasıl ayarlandığını gösterir:

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

Yukarıdaki işleyici bloğunda dönmeniz YES/true durumunda uygulamanızın kullanıcı izni alması ve aşağıdaki API'yi kullanarak sonucu SDK'ya göndermesi gerekir. Yukarıdaki örnekte yaptığımız gibi, bunun için bir uyarı kullanıyorsanız, çağrının sonucuna (ModalResponse) göre bu uyarıyı runModal çağırırsınız.

// 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)

Ana iş parçacığında oluşan yakalanmayan özel durumları yakalamayı etkinleştirme

AppKit ana iş parçacığında oluşan özel durumları yakalar ve uygulamanın macOS'ta kilitlenmesini önler, bu nedenle SDK bu kilitlenmeleri yakalayamaz. iOS davranışını taklit etmek için SDK başlatmadan önce bayrağı ayarlayın NSApplicationCrashOnExceptions , bu bayrak uygulamanın yakalanmayan özel durumlarda kilitlenmesine izin verir ve SDK bunları bildirebilir.

[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"NSApplicationCrashOnExceptions" : @YES }];
UserDefaults.standard.register(defaults: ["NSApplicationCrashOnExceptions": true])

Not

App Center SDK'sı 1.10.0 ve altındaki sürümlerde bayrağı otomatik olarak ayarlar. Sürüm 1.11.0'dan itibaren bu bayrak artık otomatik olarak ayarlanmadı.

Uygulama ana sınıfının yöntem çağrılarının App Center Kilitlenmelerine iletilmesi devre dışı bırak

App Center Crashes SDK'sı, uygulama ana sınıfının yöntem çağrılarından bazılarını ileterek tümleştirmesini geliştirmek için kaydırmayı kullanır. Yöntem kaydırma, çalışma zamanında yöntemlerin uygulanmasını değiştirmenin bir yoludur. Herhangi bir nedenle kaydırma kullanmak istemiyorsanız (örneğin, belirli bir ilke nedeniyle), Kilitlenmelerin ana iş parçacığında oluşan özel durumları doğru bir şekilde raporlaması için uygulamanın reportException: ve sendEvent: yöntemlerini kendiniz geçersiz kılmalısınız.

  1. ReportExceptionApplication.m dosyası oluşturun ve aşağıdaki uygulamayı ekleyin:

    @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
    

    Not

    Swift ile try/catch çalışmaz.NSException Bu özel durumlar yalnızca Objective-C'de işlenebilir.

  2. Info.plist dosyasını açın ve Principal sınıf alanındaki NSApplication değerini bu örnekteki uygulama sınıfı adınız ReportExceptionApplication ile değiştirin.

  3. App Center SDK'sında kaydırmayı devre dışı bırakmak için anahtarı Info.plist dosyasına ekleyin AppCenterApplicationForwarderEnabled ve değerini olarak 0ayarlayın.

Kilitlenme günlüğü için gönderme durumu hakkında bilgi alma

Bazen uygulamanızın kilitlenme durumunu bilmek istersiniz. Sık karşılaşılan bir kullanım örneği, kullanıcılara uygulamanızın kilitlenme raporu gönderdiğini bildiren kullanıcı arabirimini göstermek veya uygulamanızın başlatma işleminden sonra hızla kilitlenmesi durumunda kilitlenme günlüklerinin gönderildiğinden emin olmak için uygulamanın davranışını ayarlamak istemenizdir. CrashesDelegate-protocol, neler olduğu hakkında bildirim almak için uygulamanızda kullanabileceğiniz üç farklı geri çağırma tanımlar:

SDK bir kilitlenme günlüğü göndermeden önce aşağıdaki geri arama çağrılır

- (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.
}

Uç noktada ağ sorunları veya kesinti olması ve uygulamayı yeniden başlatmanız durumunda işlem willSendErrorReport yeniden başlatıldıktan sonra yeniden tetikleniyor.

SDK bir kilitlenme günlüğünü başarıyla gönderdikten sonra aşağıdaki geri arama çağrılır

- (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 bir kilitlenme günlüğü gönderemezse aşağıdaki geri çağırma çağrılır

- (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.
}

Alma didFailSendingErrorReport , 4xx kodu gibi kurtarılamaz bir hata oluştuğu anlamına gelir. Örneğin, 401 yanlış anlamına gelir appSecret .

Bu geri arama bir ağ sorunuysa tetiklenmemiştir. Bu durumda SDK yeniden denemeye devam eder (ve ağ bağlantısı kapalıyken yeniden denemeleri duraklatır).

Kilitlenme raporuna ek ekleme

Kilitlenme raporuna ikili ve metin ekleri ekleyebilirsiniz. SDK bunları kilitlenmeyle birlikte gönderir, böylece bunları App Center portalında görebilirsiniz. Önceki uygulama başlatmalarından depolanan kilitlenme gönderilmeden hemen önce aşağıdaki geri arama çağrılır. Kilitlenme gerçekleştiğinde çağrılmayacak. Aşağıda kilitlenmeye metin ve resim ekleme örneği verilmiştir:

- (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!]
}

Not

Boyut sınırı şu anda 7 MB'tır. Daha büyük bir ek göndermeye çalışmak bir hatayı tetikler.

Çalışma zamanında App Center Kilitlenmelerini etkinleştirme veya devre dışı bırakma

Çalışma zamanında App Center Kilitlenmelerini etkinleştirebilir ve devre dışı bırakabilirsiniz. Devre dışı bırakırsanız SDK, uygulama için kilitlenme bildirimi yapmaz.

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

App Center Kilitlenmelerini yeniden etkinleştirmek için aynı API'yi kullanın ancak parametre olarak geçirin YES/true .

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

Durum, uygulama başlatmaları arasında cihazın depolama alanında kalıcı hale geldi.

Not

Bu yöntem yalnızca başlatıldıktan sonra Crashes kullanılmalıdır.

App Center Kilitlenmelerinin etkinleştirilip etkinleştirilmediğini denetleyin

App Center Kilitlenmelerinin etkinleştirilip etkinleştirilmediğini de de de kontrol edebilirsiniz:

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

Not

Bu yöntem yalnızca başlatıldıktan sonra Crashes kullanılmalıdır, her zaman başlamadan önce döndürülecektir false .

Mach özel durum işlemesini devre dışı bırakma

App Center Kilitlenmeleri varsayılan olarak Mach özel durum işleyicisini kullanarak Mach özel durum işleyicisini kullanarak Mach özel durum sunucusu aracılığıyla önemli sinyalleri (örneğin yığın taşmalarını) yakalar.

disableMachExceptionHandler-method, bir Mach özel durum sunucusu aracılığıyla önemli sinyallerin yakalanmasını devre dışı bırakma seçeneği sağlar. Mach özel durum işleyicisini devre dışı bırakmak istiyorsanız SDK'yı başlatmadan önce bu yöntemi çağırmanız gerekir. Tipik kurulum kodunuz şöyle görünür:

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