Firebase Crashlytics SDK로 업그레이드

이제 새로운 공식 Firebase Crashlytics SDK를 사용하여 앱에서 Crashlytics를 설정할 수 있습니다. 이 SDK는 다른 Firebase 제품과의 일관성이 향상되었고 보다 직관적으로 사용할 수 있는 개선된 API를 제공합니다.

이 가이드에서는 기존 Fabric SDK에서 새 SDK로 업그레이드하는 방법을 설명합니다. 필요한 경우 새 API에 적용된 변경사항, 변경 사유, 코드 업데이트 방법도 설명합니다.

시작하기 전에

1단계: Firebase 구성 파일 추가

  1. 프로젝트 설정을 엽니다. 내 앱 카드에서 구성 파일이 필요한 앱의 번들 ID를 선택합니다.

  2. GoogleService-Info.plist 다운로드를 클릭하여 Firebase Apple 플랫폼 구성 파일(GoogleService-Info.plist)을 가져옵니다.

  3. 구성 파일을 Xcode 프로젝트의 루트로 이동합니다. 메시지가 표시되면 모든 대상에 구성 파일을 추가하도록 선택합니다.

프로젝트에 번들 ID가 여러 개 있으면 각 앱에 자체 GoogleService-Info.plist 파일이 포함되도록 각 번들 ID를 Firebase Console에서 등록된 앱과 연결해야 합니다.

2단계: Firebase Crashlytics SDK 추가

  1. CocoaPods에서 모든 대상의 FabricCrashlytics 포드를 Firebase/Crashlytics 포드로 바꿉니다.

    # Add the pod for Firebase Crashlytics
    pod 'Firebase/Crashlytics'
    # Recommended: Add the Firebase pod for Google Analytics pod 'Firebase/Analytics'
  2. Fabric Answers 및 타사 키트의 종속 항목과 같은 타사 종속 항목을 Fabric에서 직접 제거하거나 삭제합니다.

  3. 포드를 설치 및 업데이트하고 .xcworkspace 파일을 열어 Xcode에서 프로젝트를 확인합니다.

    pod install
    open YOUR_PROJECT.xcworkspace

3단계: 코드 업데이트

  1. Xcode에서 앱을 다시 빌드한 다음 .xcworkspace 파일을 다시 엽니다.

  2. 다음 SDK 변경사항을 검토하고 코드를 적절하게 업데이트합니다.


이제 Crashlytics가 Firebase 설치 ID를 기반으로 ID를 순환합니다.

Crashlytics는 Crashlytics 설치 UUID를 사용하여 앱의 인스턴스를 식별하고 사용자의 데이터를 사용자 기기와 연결합니다. 이전에는 기기의 광고 ID가 변경되면 Crashlytics가 사용자의 설치 UUID를 순환했습니다. 이제는 사용자의 Firebase 설치 ID(FID)를 기반으로 설치 UUID를 순환합니다. 자세한 내용은 Firebase 설치 ID 관리를 참조하세요.

변경 사유

FID를 사용하여 다른 Firebase SDK와의 일관성을 높입니다.


이제 실행 및 업로드 기호 스크립트가 FirebaseCrashlytics에 제공됩니다.

이제 새 FirebaseCrashlytics 라이브러리에서 runupload-symbols 스크립트에 액세스할 수 있습니다. 빌드 프로세스 중 언제든 upload-symbols를 호출해 dSYM을 직접 업로드할 수 있습니다.

또한 Fabric의 API_KEYBUILD_SECRET은 더 이상 새 SDK에 포함되지 않습니다. 대신 Crashlytics는 앱의 GoogleService-info.plist 파일을 사용하여 앱과 Firebase 프로젝트에 연결하고 이전 비정상 종료 데이터를 보관합니다.

Fabric SDK

${PODS_ROOT}/Fabric/run API_KEY BUILD_SECRET
/path/to/pods/directory/Fabric/upload-symbols

Firebase Crashlytics SDK

${PODS_ROOT}/FirebaseCrashlytics/run
/path/to/pods/directory/FirebaseCrashlytics/upload-symbols

변경 사유

Crashlytics는 더 이상 Fabric SDK를 종속 항목으로 사용하지 않으므로 CLI 도구를 새 라이브러리로 이전할 예정입니다.


Crashlytics 라이브러리의 이름이 FirebaseCrashlytics로 변경되었습니다.

앱에서 가져오기 경로를 업데이트합니다.

Fabric SDK

Swift

import Crashlytics

Objective-C

@import Crashlytics

Firebase Crashlytics SDK

Swift

import FirebaseCrashlytics

Objective-C

@import FirebaseCrashlytics

변경 사유

Crashlytics 라이브러리의 이름을 업데이트하여 다른 Firebase 라이브러리(예: FirebaseFirestoreFirebaseAuth)와의 일관성을 높입니다.


FirebaseCrashlytics가 Fabric SDK에서 더 이상 작동하지 않습니다.

이제 FirebaseCrashlytics는 Firebase Crashlytics SDK로만 초기화할 수 있습니다. Swift에서 FirebaseApp.configure를 호출하거나 Objective-C에서 [FIRApp configure]를 호출하여 FirebaseCrashlytics의 인스턴스를 시작할 수 있습니다.

application:didFinishLaunchingWithOptions에서 Fabric.withstartWithAPIKey 호출을 FirebaseApp 호출로 바꿉니다.

Fabric SDK

Swift

Fabric.with([Crashlytics.self])

Objective-C

[Fabric with:@[[Crashlytics class]]];
+ startWithAPIKey:
+ startWithAPIKey:delegate:

Firebase Crashlytics SDK

Swift

FirebaseApp.configure()

Objective-C

[FIRApp configure];

변경 사유

새 메서드로 Crashlytics를 초기화하는 방법이 다른 Firebase 서비스를 초기화하는 방법과 일치합니다.


비정상 종료 및 throwException 메서드가 삭제되었습니다.

새 SDK에는 더 이상 crash 또는 throwException 메서드가 포함되지 않습니다. 대신 Swift의 fatalError 또는 Objective-C의 비어 있는 배열을 사용하여 오류를 강제로 적용합니다.

Firebase Crashlytics SDK

Swift

// Force a test crash
fatalError()

Objective-C

// Force a test crash
@[][1];

변경 사유

여러 가지 이유로 다른 종류의 비정상 종료가 발생하지만 이 메서드는 앱의 비정상 종료가 런타임 도중 발생했는지 아니면 앱의 네이티브 SDK에서 발생했는지 명확하게 나타내지 않습니다.


sharedInstance 메서드의 이름이 crashlytics로 변경되었습니다.

새 SDK에는 더 이상 sharedInstance 메서드가 포함되지 않습니다. Crashlytics를 초기화하려면 crashlytics를 대신 사용합니다. 자세한 내용은 Swift 또는 Objective-C를 참조하세요. 앱 대리자에서 초기화 스크립트를 업데이트합니다.

Fabric SDK

Swift

Crashlytics.sharedInstance()

Objective-C

[Crashlytics sharedInstance];

Firebase Crashlytics SDK

Swift

Crashlytics.crashlytics()

Objective-C

[FIRCrashlytics crashlytics];

변경 사유

다른 Firebase SDK와 일관되도록 인스턴스 getter 메서드의 이름을 바꿨습니다.


setUserIdentifier가 setUserID로 변경되고 setUserName 및 setUserEmail이 삭제되었습니다.

이전에는 setUserNamesetUserEmail을 사용하여 비정상 종료와 관련된 이름이나 이메일을 설정했지만 더 이상 이러한 메서드를 정의하지 않습니다. 사용자의 ID를 설정하는 데 선호되는 새로운 방법은 setUserID를 사용하는 것입니다.

Fabric SDK

Swift

Crashlytics.sharedInstance().setUserIdentifier("user_id")

Crashlytics.sharedInstance().setUserEmail("user_email")

Crashlytics.sharedInstance().setUserName("user_name")

Objective-C

[[Crashlytics sharedInstance] setUserIdentifier:@"user_id"];

[[Crashlytics sharedInstance] setUserEmail:@"user_email"];

[[Crashlytics sharedInstance] setUserName:@"user_name"];

Firebase Crashlytics SDK

Swift

Crashlytics.crashlytics().setUserID("user_id")

Objective-C

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

변경 사유

다른 Firebase API와 일관되도록 메서드 이름 setUserID를 사용했고 Crashlytics를 통해 PII 로깅을 사용하지 않도록 하기 위해 setUserNamesetUserEmail을 삭제했습니다.


CLSLogv 및 CLSNSLogv가 로깅 함수로 대체되었습니다.

새 SDK에는 더 이상 CLSLogv 또는 CLSNSLogv 함수가 포함되지 않습니다. 커스텀 로그 메시지를 추가하려면 Crashlytics 라이브러리에 새 로깅 메서드를 사용하세요. 새 메서드는 더 이상 stdout 또는 NSLog에 출력되지 않습니다. 이 동작을 유지하려면 래퍼를 작성하는 것이 좋습니다.

Fabric SDK

Swift

CLSLogv("%@, %@", getVaList([first_arg, second_arg]))

CLSNSLogv("%@, %@", getVaList([first_arg, second_arg]))

Objective-C

CLSLog(@"%@, %@", first_arg, second_arg);
CLSNSLog(@"%@, %@", first_arg, second_arg);

CLSLogv(@"%@, %@", args_va_list);
CLSNSLogv(@"%@, %@", args_va_list);

CLS_LOG(@"%@, %@", first_arg, second_arg);

Firebase Crashlytics SDK

Swift

Crashlytics.crashlytics().log("\(first_arg), \(second_arg)")

Crashlytics.crashlytics().log(format: "%@, %@", arguments: getVaList([first_arg, second_arg]))

Objective-C

[[FIRCrashlytics crashlytics] log:@"first_arg, second_arg"];

[[FIRCrashlytics crashlytics] logWithFormat:@"%@, %@", first_arg, second_arg];

CLS_LOG를 사용한 경우 로그 구문에 파일 이름과 줄 번호를 계속 가져오려면 헤더 파일에 다음을 추가하세요.

#define CLS_LOG(__FORMAT__, ...) [[FIRCrashlytics crashlytics] logWithFormat:@"%s line %d $ " __FORMAT__, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__]

변경 사유

새 메서드에는 인스턴스가 필요하며, 이 인스턴스를 사용하면 코드를 테스트하기도 더 쉽습니다.


setCustomValue가 setObjectValue, setIntValue, setFloatValue, setBoolValue를 대체합니다.

커스텀 setter 메서드는 더 이상 새 SDK에 포함되지 않습니다. 이전에는 이 메서드를 사용하여 비정상 종료 보고서와 함께 전송할 키-값 쌍을 설정할 수 있었습니다. 이제 setCustomValue:forKey를 사용하여 모든 데이터 유형의 키-값 쌍을 설정할 수 있습니다.

Fabric SDK

Swift

Crashlytics.sharedInstance().setObjectValue("value", forKey: "object_key")

Crashlytics.sharedInstance().setIntValue(100, forKey: "int_key")

Crashlytics.sharedInstance().setFloatValue(99.9, forKey: "float_key")

Crashlytics.sharedInstance().setBoolValue(true, forKey: "bool_key")

Objective-C

[[Crashlytics sharedInstance] setObjectValue:@"key" forKey:@"object_key"];

[[Crashlytics sharedInstance] setIntValue:100 forKey:@"int_key"];

[[Crashlytics sharedInstance] setFloatValue:99.9 forKey:@"float_key"];

[[Crashlytics sharedInstance] setBoolValue:YES forKey:@"bool_key"];

Firebase Crashlytics SDK

Swift

Crashlytics.crashlytics().setCustomValue("value", forKey: "object_key")

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

Crashlytics.crashlytics().setCustomValue(99.9, forKey: "float_key")

Crashlytics.crashlytics().setCustomValue(true, forKey: "bool_key")

Objective-C

[[FIRCrashlytics crashlytics] setCustomValue:@"value" forKey:@"object_key"];

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

[[FIRCrashlytics crashlytics] setCustomValue:@(99.9) forKey:@"float_key"];

[[FIRCrashlytics crashlytics] setCustomValue:@YES forKey:@"bool_key"];

변경 사유

새 메서드 이름이 Crashlytics에 대해 고유하고 Crashlytics가 키-값을 준수하지 않음이 명확합니다.


recordCustomExceptionName:reason:frameArray:가 Exception Model API로 대체되었습니다.

앱을 네이티브가 아닌 환경(예: 자바스크립트 또는 Unity)에서 실행하는 경우 Exception Model API를 사용하여 앱의 네이티브 예외 형식으로 비정상 종료 메타데이터를 보고할 수 있습니다.

Fabric SDK

Swift

let topFrame = CLSStackFrame() topFrame.symbol = "doSomethingBad" topFrame.fileName = "bad.cc" topFrame.lineNumber = 23

let middleFrame = CLSStackFrame()
middleFrame.symbol = "doOtherStuff"
middleFrame.fileName = "stuff.cc"
middleFrame.lineNumber = 23;

let bottomFrame = CLSStackFrame()
bottomFrame.symbol = "main"
bottomFrame.fileName = "main.cc"
bottomFrame.lineNumber = 123

Crashlytics.sharedInstance().recordCustomExceptionName("FooException",
                                                       reason: "There was a foo.",
                                                       frameArray: [topFrame, middleFrame, bottomFrame])

Objective-C

CLSStackFrame *topFrame = [[CLSStackFrame alloc] init];
topFrame.symbol = @"doSomethingBad";
topFrame.fileName = @"bad.cc";
topFrame.lineNumber = 23;

CLSStackFrame *middleFrame = [[CLSStackFrame alloc] init];
middleFrame.symbol = @"doOtherStuff";
middleFrame.fileName = @"stuff.cc";
middleFrame.lineNumber = 23;

CLSStackFrame *bottomFrame = [[CLSStackFrame alloc] init];
bottomFrame.symbol = @"main";
bottomFrame.fileName = @"main.cc";
bottomFrame.lineNumber = 123;

[[Crashlytics sharedInstance] recordCustomExceptionName:@"FooException"
                                                 reason:@"There was a foo."
                                             frameArray:@[topFrame, middleFrame, bottomFrame]];

Firebase Crashlytics SDK

Swift

var  ex = ExceptionModel.init(name:"FooException", reason:"There was a foo.")
ex.stackTrace = [
  StackFrame.init(symbol:"makeError" fileName:"handler.js" lineNumber:495),
  StackFrame.init(symbol:"then" fileName:"routes.js" lineNumber:102),
  StackFrame.init(symbol:"main" fileName:"app.js" lineNumber:12),
]

crashlytics.record(exceptionModel:ex)

Objective-C

model.stackTrace = @[
  [FIRStackFrame stackFrameWithSymbol:@"makeError" fileName:@"handler.js" lineNumber:495],
  [FIRStackFrame stackFrameWithSymbol:@"then" fileName:@"routes.js" lineNumber:102],
  [FIRStackFrame stackFrameWithSymbol:@"main" fileName:@"app.js" lineNumber:12],
];

변경 사유

이 기능은 오랫동안 요청되었으며, 이 기능을 사용하면 Crashlytics를 Unity, Flutter 또는 React Native와 같은 다른 플랫폼으로 확장할 수 있습니다.



CrashlyticsDelegate가 비정상 종료 보고서를 처리하는 별도의 메서드로 대체되었습니다.

이제 비정상 종료 보고서를 처리하는 새로운 메서드를 사용할 수 있습니다.

  • 이제 didFinishLaunchingWithOptions가 새 핸들러 checkForUnsentReportsWithCompletion으로 대체됩니다.

  • 이제 crashlyticsDidDetectReportForLastExecutiondidCrashDuringPreviousExecution으로 대체됩니다. didCrashDuringPreviousExecution을 사용하면 앱의 마지막 실행 중에 발생하는 비정상 종료를 편리하게 감지할 수 있습니다.

  • 이제 crashlyticsCanUseBackgroundSessions가 true로 영구 설정됩니다.

  • 위임에서 CLSReport 객체 검사가 더 이상 지원되지 않습니다.

기본적으로 Crashlytics는 시작 시 비정상 종료 보고서를 자동으로 업로드하지만 이전에는 didFinishLaunchingWithOptions를 호출하여 사용자가 비정상 종료 보고에 동의할 수 있었습니다. 이제 setCrashlyticsCollectionEnabled=false를 호출하여 자동 비정상 종료 보고를 사용 중지하면 Crashlytics에서 checkForUnsentReportsWithCompletion을 호출하여 앱이 비정상 종료될 때 사용자가 비정상 종료 보고서를 보낼지 여부를 선택하도록 할 수 있습니다. 그런 다음 사용자가 선택하면 sendUnsentReports를, 사용자가 선택 해제하면 deleteUnsentReports를 호출할 수 있습니다.

checkForUnsentReportsWithCompletion 외부에서 sendUnsentReportsdeleteUnsentReports를 호출할 수도 있습니다. 예를 들어 사용자가 비정상 종료 보고서를 보낼 수 있도록 포괄적 승인 또는 비승인을 부여한 경우 비정상 종료 보고를 영구 설정하거나 사용 중지할 수 있습니다. 앱이 수명 주기 초반에 비정상 종료되면 비정상 종료 보고서를 받지 못할 수 있습니다.

Fabric SDK

Swift

class YourClassName: CrashlyticsDelegate {

  func application(_ application: UIApplication, didFinishLaunchingWithOptions

    ...
    Crashlytics.sharedInstance().delegate = self
    ...

    return true
  }

  func crashlyticsDidDetectReport(forLastExecution report: CLSReport, completionHandler: @escaping (Bool) -> Void) {
    /* ... handle unsent reports */
  }

  func crashlyticsCanUseBackgroundSessions(_ crashlytics: Crashlytics) -> Bool {
    return true
  }
}

Objective-C

@interface YourClassName <CrashlyticsDelegate> ()
@end

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

  ...
  [[Crashlytics sharedInstance] setDelegate:self];
  ...

  return YES;
}

-(void)crashlyticsDidDetectReportForLastExecution:(CLSReport *)report completionHandler:(void (^)(BOOL submit))completionHandler {
  // ... handle unsent reports
}

-(BOOL)crashlyticsCanUseBackgroundSessions:(Crashlytics *)crashlytics {
  return YES;
}

@end

Firebase Crashlytics SDK

Swift

/* You must set setCrashlyticsCollectionEnabled to false in order to use
checkForUnsentReportsWithCompletion. */

Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(false)

Crashlytics.crashlytics().checkForUnsentReports { hasUnsentReport in
  let hasUserConsent = false
  // ...get user consent.

  if hasUserConsent && hasUnsentReport {
    Crashlytics.crashlytics().sendUnsentReports()
  } else {
    Crashlytics.crashlytics().deleteUnsentReports()
  }
}

// Detect when a crash happens during your app's last run.
if Crashlytics.crashlytics().didCrashDuringPreviousExecution() {
  // ...notify the user.
}

Objective-C

/* You must set setCrashlyticsCollectionEnabled to false in order to use
checkForUnsentReportsWithCompletion. */

[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:false];

[[FIRCrashlytics crashlytics] checkForUnsentReportsWithCompletion:^(BOOL hasUnsentReports) {
  BOOL hasConsent = false;
  // ...get consent from user.

  if (hasConsent && hasUnsentReports) {
    [[FIRCrashlytics crashlytics] sendUnsentReports];
  } else {
    [[FIRCrashlytics crashlytics] deleteUnsentReports];
  }
}];

// Detect when a crash happens during your app's last run.
if ([[FIRCrashlytics crashlytics] didCrashDuringPreviousExecution]) {
  // ...notify the user.
}

변경 사유

새로운 메서드를 사용하면 앱의 비정상 종료 보고 동작을 더욱 효과적으로 제어할 수 있습니다. 또한 Crashlytics를 초기화하기 전에 더 이상 CrashlyticsDelegate를 설정할 필요가 없습니다.


firebase_crashlytics_collection_enabled가 FirebaseCrashlyticsCollectionEnabled로 대체되었습니다.

Info.plist에서 FirebaseCrashlyticsCollectionEnabled를 false로 설정하면 Crashlytics는 시작 시 비정상 종료 보고서 자동 전송을 중지합니다. 앱을 처음 실행한 후 Crashlytics.h에서 setCrashlyticsCollectionEnabledfalse로 설정하여 오류 보고를 사용 중지할 수도 있지만 setCrashlyticsCollectionEnabled는 이 플래그를 재정의합니다.

Info.plist에서 firebase_crashlytics_collection_enabled 키를 바꿔 자동 수집을 사용 중지합니다.

  • 키: FirebaseCrashlyticsCollectionEnabled

  • 값: false

앱을 처음 실행한 후 Crashlytics.h에 다음을 추가하여 자동 수집을 사용 중지할 수 있습니다.

Firebase Crashlytics SDK

Swift

// setCrashlyticsCollectionEnabled is set to true by default.
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(false)

Objective-C

// setCrashlyticsCollectionEnabled is set to true by default.
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:false];

변경 사유

이제 자동 비정상 종료 보고를 사용 중지할 때 Crashlytics에서 전송되지 않은 비정상 종료 보고서를 처리하는 방법을 더욱 효과적으로 제어할 수 있습니다. FirebaseCrashlyticsCollectionEnabled를 false로 설정하면 앱에서 언제든 checkForUnsentReportsWithCompletion을 호출하고 사용자의 선택에 따라 전송되지 않은 보고서를 보내거나 삭제할 수 있습니다.


이제 Crashlytics는 항상 백그라운드 세션을 사용합니다.

이전에는 앱에서 백그라운드 세션을 지원하지 않도록 crashlyticsCanUseBackgroundSessions를 false로 설정했었습니다. 이제 crashlyticsCanUseBackgroundSessions가 항상 true로 설정됩니다.

변경 사유

백그라운드 세션을 지원하지 않는 iOS 버전 7.0 이하 또는 macOS 버전 OS X 10.9 미만은 더 이상 지원되지 않습니다.


Crashlytics는 Google 애널리틱스에서 수집한 데이터만 사용할 수 있습니다.

Firebase Crashlytics SDK로 업그레이드한 후 Fabric Answers에서 더 이상 데이터를 수집할 수 없습니다. 비정상 종료가 발생하지 않은 사용자와 탐색경로의 측정항목을 가져오려면 Google 애널리틱스를 사용하도록 전환하세요. 이전의 Answers 데이터는 Firebase로 마이그레이션할 수 없습니다.

Google 애널리틱스 시작에서 앱에 Google 애널리틱스를 추가하는 방법을 알아보세요.

변경 사유

이제 Google 애널리틱스를 통해 비정상 종료 데이터에 대한 자세한 정보를 파악할 수 있습니다. 애널리틱스를 사용하면 Firebase Console에서 앱 통계를 계속 수집할 수 있습니다.

다음 단계