반응형
iOS 앱 크래시 발생 시 확인하는 방법
iOS 앱 크래시를 코드로 감지하거나 수집하는 방법은 제한적입니다.
App Store 정책을 지키면서 안정적으로 로그를 남기려면, MetricKit + Exception Handler + Breadcrumb Logger + Crashlytics/Sentry 조합이 가장 효과적입니다.
1. MetricKit (공식, iOS 13+)
import UIKit
import MetricKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate, MXMetricManagerSubscriber {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
MXMetricManager.shared.add(self)
return true
}
func didReceive(_ payloads: [MXDiagnosticPayload]) {
for payload in payloads {
if let crashes = payload.crashDiagnostics {
for crash in crashes {
let signal = crash.signal
let exception = crash.exceptionType
let reason = crash.terminationReason
let stack = crash.callStackTree.jsonRepresentation()
print("Crash signal: \(signal), reason: \(String(describing: reason))")
// JSON 저장 후 다음 실행 시 서버 업로드 가능
}
}
}
}
}
장점: 시스템 레벨 크래시, OOM, Hang까지 진단 가능
단점: “다음 실행 시” 전달됨 (실시간 아님)
2. NSSetUncaughtExceptionHandler (Objective-C 예외)
void UncaughtExceptionHandler(NSException *exception) {
NSString *summary = [NSString stringWithFormat:@"name=%@ reason=%@ stack=%@",
exception.name, exception.reason, exception.callStackSymbols];
// 최소한의 로그만 남기기
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
return YES;
}
장점: 간단한 예외 로그 확보
단점: Swift fatalError 등은 잡히지 않음
3. POSIX Signal Handler (SIGABRT, SIGSEGV 등)
#include <signal.h>
#include <execinfo.h>
void signalHandler(int sig) {
void *stack[64];
int frames = backtrace(stack, 64);
backtrace_symbols_fd(stack, frames, STDERR_FILENO);
_exit(1);
}
void installSignals() {
signal(SIGABRT, signalHandler);
signal(SIGSEGV, signalHandler);
signal(SIGILL, signalHandler);
signal(SIGBUS, signalHandler);
}
주의: 신호 핸들러에서는 파일/네트워크 접근 금지.
사용법: Swift에서 브리징 후 installSignals() 호출.
4. Breadcrumb 로깅 (비동기 안전 로그)
struct Breadcrumb: Codable { let t: TimeInterval; let msg: String }
final class Bread {
static let shared = Bread()
private let url = FileManager.default.temporaryDirectory.appendingPathComponent("crumbs.log")
private let q = DispatchQueue(label: "crumbs", qos: .utility)
func add(_ msg: String) {
let b = Breadcrumb(t: Date().timeIntervalSince1970, msg: msg)
q.async {
if let data = try? JSONEncoder().encode(b) {
try? FileHandle(forWritingTo: self.url).flatMap {
try? $0.seekToEnd()
try? $0.write(contentsOf: data + Data([0x0A]))
try? $0.close()
} ?? { try? data.write(to: self.url) }()
}
}
}
}
앱 주요 이벤트(화면 진입, 요청 성공 등)를 Breadcrumb으로 남겨 크래시 직전 흐름을 복원.
5. OOM(Out Of Memory) 탐지 요령
체크 포인트설명
| last_run.json 파일 삭제 여부 | 비정상 종료 감지 |
| didReceiveMemoryWarning 횟수 증가 | 직전 메모리 부족 징후 |
| MetricKit OOM 리포트 | iOS 14+ 에서 수신 가능 |
6. 서드파티 크래시 SDK
Firebase Crashlytics
import FirebaseCore
import FirebaseCrashlytics
FirebaseApp.configure()
Crashlytics.crashlytics().log("Entered GameScene")
Crashlytics.crashlytics().setCustomValue("stage5", forKey: "level")
장점: 실시간 대시보드, dSYM 자동 업로드, 버전별 그룹핑
단점: 커스텀 전송 제어 어려움
Sentry
- 장점: 성능 트레이스 + 크래시 통합 수집, breadcrumb 자동 저장
- 설정: SentrySDK.start { $0.dsn = "YOUR_DSN" }
7. 실시간으로 잡을 수 없는 것들
항목설명
| Watchdog 종료 | 런치/백그라운드 제한시간 초과, 감지 불가 |
| SIGKILL | OS 강제 종료, 콜백 없음 |
| fatalError() | NSSetUncaughtExceptionHandler에 안 잡힘 |
8. 최소 구성 템플릿
- MetricKit 구독 (공식 리포트)
- Breadcrumb 로거 (앱 이벤트 추적)
- NSException / Signal 핸들러 (보조)
- Crashlytics 또는 Sentry (실시간 수집)
- 다음 실행 시 업로드 파이프라인 구축
9. 심볼리케이션
- dSYM 자동 업로드 (upload-symbols 스크립트)
- 로컬 테스트: atos -o YourApp.dSYM/Contents/Resources/DWARF/YourApp 0xADDRESS
결론
- 실시간 감지는 불가능하나, “다음 실행 시 + Breadcrumb 조합” 으로 완전한 분석 가능.
- 공식 MetricKit + Firebase Crashlytics/Sentry 조합이 현실적이며, App Store 정책에도 안전.
- 크래시 순간에는 I/O, 네트워크 전송을 절대 시도하지 말고, 다음 실행 시 업로드하도록 구성하세요.
반응형
'Dev Study > iOS' 카테고리의 다른 글
| 화면을 이미지로 전환 (UIView -> UIImage, View -> Image) (0) | 2025.11.06 |
|---|---|
| WKWebView 실전 팁 모음 (iOS 15+) (0) | 2025.11.06 |
| Swift 날짜 포맷(DateFormatter) 치트시트 & 사용법 정리 (iOS) (0) | 2025.11.06 |
| iOS 위젯에서 앱 특정 화면으로 이동하는 방법 (0) | 2025.11.06 |
| iOS DocC 완전 정복 가이드: Swift 문서화를 위한 최고의 도구 (0) | 2025.11.06 |
| iOS TDD 완벽 가이드: 개념부터 실전까지 (0) | 2025.11.06 |
| iOS 개발자를 위한 Tuist 완벽 가이드 (0) | 2025.11.03 |
| Mac OS 업데이트 이후 Xcode 실행 (0) | 2024.12.11 |


