欢迎参加我们将于 2022 年 10 月 18 日举办的 Firebase 峰会(线上线下同时进行),了解 Firebase 如何帮助您加快应用开发速度、满怀信心地发布应用并在之后需要时轻松地扩大应用规模。立即报名

התאם אישית את דוחות הקריסה של Firebase Crashlytics

מדריך זה מתאר כיצד להתאים אישית את דוחות הקריסה שלך באמצעות Firebase Crashlytics SDK. כברירת מחדל, Crashlytics אוספת אוטומטית דוחות קריסה עבור כל משתמשי האפליקציה שלך (אתה יכול לבטל את הדיווח האוטומטי על קריסה ולהפעיל דיווח הסכמה עבור המשתמשים שלך במקום זאת). Crashlytics מספקת ארבעה מנגנוני רישום מחוץ לקופסה: מפתחות מותאמים אישית, יומנים מותאמים אישית , מזהי משתמש וחריגים שנתפסו .

הוסף מפתחות מותאמים אישית

מפתחות מותאמים אישית עוזרים לך לקבל את המצב הספציפי של האפליקציה שלך לקראת קריסה. אתה יכול לשייך צמדי מפתח/ערך שרירותיים לדוחות הקריסה שלך, ולאחר מכן להשתמש במפתחות המותאמים אישית כדי לחפש ולסנן דוחות קריסה במסוף Firebase.

  • בלוח המחוונים של Crashlytics , תוכל לחפש בעיות התואמות למפתח מותאם אישית.
  • כאשר אתה בודק בעיה ספציפית במסוף, אתה יכול להציג את המפתחות המותאמים אישית המשויכים לכל אירוע (כרטיסיית המשנה Keys ) ואפילו לסנן את האירועים לפי מפתחות מותאמים אישית (תפריט סינון בראש העמוד).

השתמש בשיטת setCustomValue כדי להגדיר זוגות מפתח/ערך. לדוגמה:

מָהִיר

// Set int_key to 100.
Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key")

// Set str_key to "hello".
Crashlytics.crashlytics().setCustomValue("hello", forKey: "str_key")

Objective-C

בעת הגדרת מספרים שלמים, בוליאנים או צפים, תיבת הערך כ @( value ) .

// Set int_key to 100.
[[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"];

// Set str_key to "hello".
[[FIRCrashlytics crashlytics] setCustomValue:@"hello" forKey:@"str_key"];

ניתן גם לשנות את הערך של מפתח קיים על ידי קריאה למפתח והגדרתו לערך אחר. לדוגמה:

מָהִיר

Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key")

// Set int_key to 50 from 100.
Crashlytics.crashlytics().setCustomValue(50, forKey: "int_key")

Objective-C

[[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"];

// Set int_key to 50 from 100.
[[FIRCrashlytics crashlytics] setCustomValue:@(50) forKey:@"int_key"];

הוסף צמדי מפתח/ערך בכמות גדולה על ידי שימוש בשיטת setCustomKeysAndValues ​​עם NDictionary כפרמטר היחיד:

מָהִיר

let keysAndValues = [
                 "string key" : "string value",
                 "string key 2" : "string value 2",
                 "boolean key" : true,
                 "boolean key 2" : false,
                 "float key" : 1.01,
                 "float key 2" : 2.02
                ] as [String : Any]

Crashlytics.crashlytics().setCustomKeysAndValues(keysAndValues)

Objective-C

NSDictionary *keysAndValues =
    @{@"string key" : @"string value",
      @"string key 2" : @"string value 2",
      @"boolean key" : @(YES),
      @"boolean key 2" : @(NO),
      @"float key" : @(1.01),
      @"float key 2" : @(2.02)};

[[FIRCrashlytics crashlytics] setCustomKeysAndValues: keysAndValues];

הוסף הודעות יומן מותאמות אישית

כדי לתת לעצמך יותר הקשר לאירועים שהובילו לקריסה, תוכל להוסיף יומני Crashlytics מותאמים אישית לאפליקציה שלך. Crashlytics משייך את היומנים לנתוני הקריסה שלך ומציג אותם בדף Crashlytics של מסוף Firebase , תחת הכרטיסייה יומנים .

מָהִיר

השתמש ב- log() או log(format:, arguments:) כדי לעזור באיתור בעיות. אם אתה רוצה לקבל פלט יומן שימושי עם הודעות, האובייקט שאתה מעביר ל- log() חייב להתאים למאפיין CustomStringConvertible . log() מחזירה את המאפיין description שאתה מגדיר עבור האובייקט. לדוגמה:

Crashlytics.crashlytics().log("Higgs-Boson detected! Bailing out…, \(attributesDict)")

.log(format:, arguments:) פורמט ערכים שהוחזרו getVaList() . לדוגמה:

Crashlytics.crashlytics().log(format: "%@, %@", arguments: getVaList(["Higgs-Boson detected! Bailing out…", attributesDict]))

לפרטים נוספים על אופן השימוש ב log() או log(format:, arguments:) , עיין בתיעוד ההפניה של Crashlytics.

Objective-C

השתמש log או logWithFormat כדי לעזור באיתור בעיות. שים לב שאם אתה רוצה לקבל פלט יומן שימושי עם הודעות, האובייקט שאתה מעביר לכל אחת מהשיטות חייב לעקוף את מאפיין מופע description . לדוגמה:

[[FIRCrashlytics crashlytics] log:@"Simple string message"];

[[FIRCrashlytics crashlytics] logWithFormat:@"Higgs-Boson detected! Bailing out... %@", attributesDict];

[[FIRCrashlytics crashlytics] logWithFormat:@"Logging a variable argument list %@" arguments:va_list_arg];

לפרטים נוספים על אופן השימוש log וב- logWithFormat , עיין בתיעוד ההפניה של Crashlytics.

הגדר מזהי משתמש

כדי לאבחן בעיה, לעתים קרובות כדאי לדעת מי מהמשתמשים שלך חווה קריסה נתונה. Crashlytics כולל דרך לזהות משתמשים באופן אנונימי בדוחות הקריסה שלך.

כדי להוסיף מזהי משתמש לדוחות שלך, הקצה לכל משתמש מזהה ייחודי בצורה של מספר מזהה, אסימון או ערך גיבוב:

מָהִיר

Crashlytics.crashlytics().setUserID("123456789")

Objective-C

[[FIRCrashlytics crashlytics] setUserID:@"123456789"];

אם אי פעם תצטרך לנקות מזהה משתמש לאחר הגדרתו, אפס את הערך למחרוזת ריקה. ניקוי מזהה משתמש אינו מסיר רשומות Crashlytics קיימות. אם אתה צריך למחוק רשומות המשויכות למזהה משתמש, פנה לתמיכה של Firebase .

דווח על חריגים לא קטלניים

בנוסף לדיווח אוטומטי על קריסות האפליקציה שלך, Crashlytics מאפשרת לך להקליט חריגים לא קטלניים ולשלוח אותם אליך בפעם הבאה שהאפליקציה שלך תושק.

אתה יכול להקליט חריגים לא קטלניים על ידי הקלטת אובייקטי NSError בשיטת recordError . recordError לוכדת את ערימת השיחות של השרשור על ידי קריאה [NSThread callStackReturnAddresses] .

מָהִיר

Crashlytics.crashlytics().record(error: error)

Objective-C

[[FIRCrashlytics crashlytics] recordError:error];

בעת שימוש בשיטת recordError , חשוב להבין את מבנה NSError וכיצד Crashlytics משתמש בנתונים כדי לקבץ קריסות. שימוש שגוי בשיטת recordError עלול לגרום להתנהגות בלתי צפויה ועלול לגרום ל-Crashlytics להגביל את הדיווח על שגיאות מתועדות עבור האפליקציה שלך.

לאובייקט NSError יש שלושה ארגומנטים:

  • domain: String
  • code: Int
  • userInfo: [AnyHashable : Any]? = nil

שלא כמו קריסות קטלניות, שמקובצות באמצעות ניתוח עקבות מחסנית, שגיאות מתועדות מקובצות לפי domain code . זוהי הבחנה חשובה בין קריסות קטלניות לבין שגיאות מתועדות. לדוגמה:

מָהִיר

let userInfo = [
  NSLocalizedDescriptionKey: NSLocalizedString("The request failed.", comment: ""),
  NSLocalizedFailureReasonErrorKey: NSLocalizedString("The response returned a 404.", comment: ""),
  NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString("Does this page exist?", comment: ""),
  "ProductID": "123456",
  "View": "MainView"
]

let error = NSError.init(domain: NSCocoaErrorDomain,
                         code: -1001,
                         userInfo: userInfo)

Objective-C

NSDictionary *userInfo = @{
  NSLocalizedDescriptionKey: NSLocalizedString(@"The request failed.", nil),
  NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The response returned a 404.", nil),
  NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Does this page exist?", nil),
  @"ProductID": @"123456",
  @"View": @"MainView",
};

NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain
                                     code:-1001
                                 userInfo:userInfo];

כאשר אתה רושם את השגיאה למעלה, זה יוצר בעיה חדשה שמקובצת לפי NSSomeErrorDomain ו -1001 . שגיאות מתועדות נוספות המשתמשות באותם ערכי דומיין וקוד מקובצות תחת אותה בעיה. הנתונים הכלולים באובייקט userInfo מומרים לצמדי מפתח-ערך ומוצגים במקטע מפתחות/יומנים בתוך בעיה בודדת.

יומנים ומפתחות מותאמים אישית

בדיוק כמו דוחות קריסה, אתה יכול להטמיע יומנים ומפתחות מותאמים אישית כדי להוסיף הקשר ל- NSError . עם זאת, יש הבדל באילו יומנים מצורפים לקריסות לעומת שגיאות מתועדות. כאשר מתרחשת קריסה והאפליקציה מופעלת מחדש, היומנים ש-Cashlytics מאחזר מהדיסק הם אלו שנכתבו ממש עד למועד הקריסה. כאשר אתה רושם NSError , האפליקציה לא מסתיימת מיד. מכיוון ש-Crashlytics שולחת את דוח השגיאה המתועד רק בהשקת האפליקציה הבאה וחייבת להגביל את כמות השטח המוקצה עבור יומנים בדיסק, ניתן לבצע רישום מספיק לאחר NSError כך שכל היומנים הרלוונטיים יסובבו החוצה עד לזמן ש-Cashlytics שולח הדיווח מהמכשיר. זכור את האיזון הזה בעת רישום NSErrors ושימוש ביומנים ומפתחות מותאמים אישית באפליקציה שלך.

שיקולי ביצועים

זכור כי רישום NSError יכול להיות יקר למדי. בזמן שאתה מבצע את השיחה, Crashlytics לוכדת את ערימת השיחות של השרשור הנוכחי באמצעות תהליך שנקרא מחסנית. תהליך זה יכול להיות אינטנסיבי של מעבד ו-I/O, במיוחד בארכיטקטורות התומכות ב-DWARF (arm64 ו-x86). לאחר השלמת ההתנתקות, המידע נכתב לדיסק באופן סינכרוני. זה מונע אובדן נתונים אם השורה הבאה הייתה קורסת.

למרות שבטוח לקרוא ל-API זה על שרשור רקע, זכור ששיגור קריאה זו לתור אחר מאבד את ההקשר של מעקב המחסנית הנוכחי.

מה לגבי NSExceptions?

Crashlytics לא מציעה מתקן לרישום והקלטה של ​​מופעי NSException ישירות. באופן כללי, ממשקי API של Cocoa ו-Cocoa Touch אינם בטוחים במיוחד. זה אומר שלשימוש ב- @catch עלולות להיות תופעות לוואי לא מכוונות חמורות מאוד בתהליך שלך, גם כאשר משתמשים בה בזהירות רבה. לעולם אל תשתמש בהצהרות @catch בקוד שלך. אנא עיין בתיעוד של אפל בנושא.

אפשר דיווח על הסכמה

כברירת מחדל, Crashlytics אוספת אוטומטית דוחות קריסה עבור כל משתמשי האפליקציה שלך. כדי לתת למשתמשים שליטה רבה יותר על הנתונים שהם שולחים, תוכל להפעיל דיווח על הסכמה על ידי השבתת הדיווח האוטומטי ושליחת נתונים ל-Crashlytics רק כאשר תבחר בקוד שלך:

  1. כבה את האיסוף האוטומטי על ידי הוספת מפתח חדש לקובץ Info.plist שלך:

    • מפתח: FirebaseCrashlyticsCollectionEnabled
    • ערך: false
  2. אפשר איסוף עבור משתמשים נבחרים על ידי קריאה לעקיפה של איסוף הנתונים של Crashlytics בזמן ריצה. ערך העקיפה נמשך לאורך כל ההשקות של האפליקציה שלך כך ש-Crashlytics יכול לאסוף דוחות באופן אוטומטי.

    כדי לבטל את הסכמתך לדיווח על קריסה אוטומטי, העבר את false כערך העקיפה. כאשר מוגדר false , הערך החדש אינו חל עד להרצה הבאה של האפליקציה.

    מָהִיר

    Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)

    Objective-C

    [[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];

נהל נתוני Crash Insights

Crash Insights עוזר לך לפתור בעיות על ידי השוואת מעקבי הערימה האנונימיים שלך לעקבות מאפליקציות Firebase אחרות ומודיע לך אם הבעיה שלך היא חלק ממגמה גדולה יותר. עבור בעיות רבות, Crash Insights אפילו מספק משאבים שיעזרו לך לנפות באגים בקריסה.

Crash Insights משתמש בנתוני קריסה מצטברים כדי לזהות מגמות יציבות נפוצות. אם אתה מעדיף לא לשתף את נתוני האפליקציה שלך, תוכל לבטל את הסכמתך ל-Cash Insights מתפריט Crash Insights בראש רשימת הבעיות של Crashlytics במסוף Firebase .

,

מדריך זה מתאר כיצד להתאים אישית את דוחות הקריסה שלך באמצעות Firebase Crashlytics SDK. כברירת מחדל, Crashlytics אוספת אוטומטית דוחות קריסה עבור כל משתמשי האפליקציה שלך (אתה יכול לבטל את הדיווח האוטומטי על קריסה ולהפעיל דיווח הסכמה עבור המשתמשים שלך במקום זאת). Crashlytics מספקת ארבעה מנגנוני רישום מחוץ לקופסה: מפתחות מותאמים אישית, יומנים מותאמים אישית , מזהי משתמש וחריגים שנתפסו .

הוסף מפתחות מותאמים אישית

מפתחות מותאמים אישית עוזרים לך לקבל את המצב הספציפי של האפליקציה שלך לקראת קריסה. אתה יכול לשייך צמדי מפתח/ערך שרירותיים לדוחות הקריסה שלך, ולאחר מכן להשתמש במפתחות המותאמים אישית כדי לחפש ולסנן דוחות קריסה במסוף Firebase.

  • בלוח המחוונים של Crashlytics , תוכל לחפש בעיות התואמות למפתח מותאם אישית.
  • כאשר אתה בודק בעיה ספציפית במסוף, אתה יכול להציג את המפתחות המותאמים אישית המשויכים לכל אירוע (כרטיסיית המשנה Keys ) ואפילו לסנן את האירועים לפי מפתחות מותאמים אישית (תפריט סינון בראש העמוד).

השתמש בשיטת setCustomValue כדי להגדיר זוגות מפתח/ערך. לדוגמה:

מָהִיר

// Set int_key to 100.
Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key")

// Set str_key to "hello".
Crashlytics.crashlytics().setCustomValue("hello", forKey: "str_key")

Objective-C

בעת הגדרת מספרים שלמים, בוליאנים או צפים, תיבת הערך כ @( value ) .

// Set int_key to 100.
[[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"];

// Set str_key to "hello".
[[FIRCrashlytics crashlytics] setCustomValue:@"hello" forKey:@"str_key"];

You can also modify the value of an existing key by calling the key and setting it to a different value. לדוגמה:

מָהִיר

Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key")

// Set int_key to 50 from 100.
Crashlytics.crashlytics().setCustomValue(50, forKey: "int_key")

Objective-C

[[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"];

// Set int_key to 50 from 100.
[[FIRCrashlytics crashlytics] setCustomValue:@(50) forKey:@"int_key"];

Add key/value pairs in bulk by using the setCustomKeysAndValues method with an NSDictionary as the only parameter:

מָהִיר

let keysAndValues = [
                 "string key" : "string value",
                 "string key 2" : "string value 2",
                 "boolean key" : true,
                 "boolean key 2" : false,
                 "float key" : 1.01,
                 "float key 2" : 2.02
                ] as [String : Any]

Crashlytics.crashlytics().setCustomKeysAndValues(keysAndValues)

Objective-C

NSDictionary *keysAndValues =
    @{@"string key" : @"string value",
      @"string key 2" : @"string value 2",
      @"boolean key" : @(YES),
      @"boolean key 2" : @(NO),
      @"float key" : @(1.01),
      @"float key 2" : @(2.02)};

[[FIRCrashlytics crashlytics] setCustomKeysAndValues: keysAndValues];

Add custom log messages

To give yourself more context for the events leading up to a crash, you can add custom Crashlytics logs to your app. Crashlytics associates the logs with your crash data and displays them in the Crashlytics page of the Firebase console , under the Logs tab.

מָהִיר

Use log() or log(format:, arguments:) to help pinpoint issues. If you want to get a useful log output with messages, the object that you pass to log() must conform to the CustomStringConvertible property. log() returns the description property you define for the object. לדוגמה:

Crashlytics.crashlytics().log("Higgs-Boson detected! Bailing out…, \(attributesDict)")

.log(format:, arguments:) formats values returned from calling getVaList() . לדוגמה:

Crashlytics.crashlytics().log(format: "%@, %@", arguments: getVaList(["Higgs-Boson detected! Bailing out…", attributesDict]))

For more details on how to use log() or log(format:, arguments:) , refer to the Crashlytics reference documentation .

Objective-C

Use log or logWithFormat to help pinpoint issues. Note that if you want to get a useful log output with messages, the object that you pass to either method must override the description instance property. לדוגמה:

[[FIRCrashlytics crashlytics] log:@"Simple string message"];

[[FIRCrashlytics crashlytics] logWithFormat:@"Higgs-Boson detected! Bailing out... %@", attributesDict];

[[FIRCrashlytics crashlytics] logWithFormat:@"Logging a variable argument list %@" arguments:va_list_arg];

For more details on how to use log and logWithFormat , refer to the Crashlytics reference documentation .

Set user identifiers

To diagnose an issue, it's often helpful to know which of your users experienced a given crash. Crashlytics includes a way to anonymously identify users in your crash reports.

To add user IDs to your reports, assign each user a unique identifier in the form of an ID number, token, or hashed value:

מָהִיר

Crashlytics.crashlytics().setUserID("123456789")

Objective-C

[[FIRCrashlytics crashlytics] setUserID:@"123456789"];

If you ever need to clear a user identifier after you set it, reset the value to a blank string. Clearing a user identifier does not remove existing Crashlytics records. If you need to delete records associated with a user ID, contact Firebase support .

Report non-fatal exceptions

In addition to automatically reporting your app's crashes, Crashlytics lets you record non-fatal exceptions and sends them to you the next time your app launches.

You can record non-fatal exceptions by recording NSError objects with the recordError method. recordError captures the thread's call stack by calling [NSThread callStackReturnAddresses] .

מָהִיר

Crashlytics.crashlytics().record(error: error)

Objective-C

[[FIRCrashlytics crashlytics] recordError:error];

When using the recordError method, it's important to understand the NSError structure and how Crashlytics uses the data to group crashes. Incorrect usage of the recordError method can cause unpredictable behavior and may cause Crashlytics to limit reporting of logged errors for your app.

An NSError object has three arguments:

  • domain: String
  • code: Int
  • userInfo: [AnyHashable : Any]? = nil

Unlike fatal crashes, which are grouped via stack trace analysis, logged errors are grouped by domain and code . This is an important distinction between fatal crashes and logged errors. לדוגמה:

מָהִיר

let userInfo = [
  NSLocalizedDescriptionKey: NSLocalizedString("The request failed.", comment: ""),
  NSLocalizedFailureReasonErrorKey: NSLocalizedString("The response returned a 404.", comment: ""),
  NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString("Does this page exist?", comment: ""),
  "ProductID": "123456",
  "View": "MainView"
]

let error = NSError.init(domain: NSCocoaErrorDomain,
                         code: -1001,
                         userInfo: userInfo)

Objective-C

NSDictionary *userInfo = @{
  NSLocalizedDescriptionKey: NSLocalizedString(@"The request failed.", nil),
  NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The response returned a 404.", nil),
  NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Does this page exist?", nil),
  @"ProductID": @"123456",
  @"View": @"MainView",
};

NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain
                                     code:-1001
                                 userInfo:userInfo];

When you log the error above, it creates a new issue that is grouped by NSSomeErrorDomain and -1001 . Additional logged errors that use the same domain and code values are grouped under the same issue. Data contained within the userInfo object are converted to key-value pairs and displayed in the keys/logs section within an individual issue.

Logs and custom keys

Just like crash reports, you can embed logs and custom keys to add context to the NSError . However, there is a difference in what logs are attached to crashes versus logged errors. When a crash occurs and the app is relaunched, the logs Crashlytics retrieves from disk are those that were written right up to the time of the crash. When you log an NSError , the app does not immediately terminate. Because Crashlytics only sends the logged error report on the next app launch and must limit the amount of space allocated for logs on disk, it is possible to log enough after an NSError is recorded so that all relevant logs are rotated out by the time Crashlytics sends the report from the device. Keep this balance in mind when logging NSErrors and using logs and custom keys in your app.

Performance considerations

Keep in mind that logging an NSError can be fairly expensive. At the time you make the call, Crashlytics captures the current thread's call stack using a process called stack unwinding. This process can be CPU and I/O intensive, particularly on architectures that support DWARF unwinding (arm64 and x86). After the unwind is complete, the information is written to disk synchronously. This prevents data loss if the next line were to crash.

While it is safe to call this API on a background thread, remember that dispatching this call to another queue loses the context of the current stack trace.

What about NSExceptions?

Crashlytics doesn't offer a facility for logging and recording NSException instances directly. Generally speaking, the Cocoa and Cocoa Touch APIs are not exception-safe. That means the use of @catch can have very serious unintended side-effects in your process, even when used with extreme care. You should never use @catch statements in your code. Please refer to Apple's documentation on the topic.

Enable opt-in reporting

By default, Crashlytics automatically collects crash reports for all your app's users. To give users more control over the data they send, you can enable opt-in reporting by disabling automatic reporting and only sending data to Crashlytics when you choose to in your code:

  1. Turn off automatic collection by adding a new key to your Info.plist file:

    • Key: FirebaseCrashlyticsCollectionEnabled
    • Value: false
  2. Enable collection for select users by calling the Crashlytics data collection override at runtime. The override value persists across launches of your app so Crashlytics can automatically collect reports.

    To opt out of automatic crash reporting, pass false as the override value. When set to false , the new value does not apply until the next run of the app.

    מָהִיר

    Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)

    Objective-C

    [[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];

Manage Crash Insights data

Crash Insights helps you resolve issues by comparing your anonymized stack traces to traces from other Firebase apps and letting you know if your issue is part of a larger trend. For many issues, Crash Insights even provides resources to help you debug the crash.

Crash Insights uses aggregated crash data to identify common stability trends. If you'd prefer not to share your app's data, you can opt-out of Crash Insights from the Crash Insights menu at the top of your Crashlytics issue list in the Firebase console .