1. 程式人生 > >Crash Report 之第三方框架PLCrashReporter

Crash Report 之第三方框架PLCrashReporter

Crash Report 的手機一方面可以直接從iPhone裝置提取,也可以從iTunes上下載,然而這兩種方式都不是很好操作,使用者的裝置不可能隨時提供給你,使用者也不一定會向iTunes上傳crash report,那麼最好的方式就是在app裡面我們自己收集crash report,然後通過網路、郵件等方式回傳過來。
下面介紹一款crash report 收集的第三方框架 PLCrashReporter
下載地址: https://www.plcrashreporter.org/download

解壓後開啟資料夾可以在 Source 檔案下找到 iOS版本的demo,由於demo的版本過早,在iOS9下也許會執行不起來,需要稍作修改
demo中原始碼如下:

- (void)initViews
{
    _memoryWarningReached = NO;

    // Override point for customization after app launch

    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}


// this functions sends the crash data to the server
- (void)sendCrashReport
{
    [window addSubview:startupViewController.view];
    [startupViewController startCrashData];
}

可以修改如下:

- (void)initViews
{
    _memoryWarningReached = NO;

    // Override point for customization after app launch
//    window.rootViewController = [UIViewController new];

//  [window addSubview:viewController.view];
    window.rootViewController = viewController;
    [window makeKeyAndVisible];
}


//
this functions sends the crash data to the server - (void)sendCrashReport { // [window addSubview:startupViewController.view]; window.rootViewController = startupViewController; [startupViewController startCrashData]; }

demo中有將crash report基本資訊進行了打印出來,並進行上傳伺服器,我們可以修改

- (void) handleCrashReport

方法,將crash report資訊儲存為 .plcrash檔案或者.crash 檔案,然後通過http上傳給我們的伺服器或者其它操作等,修改如下:

- (void) handleCrashReport {
    PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter];
    NSData *crashData;
    NSError *error;

    // Try loading the crash report
    crashData = [crashReporter loadPendingCrashReportDataAndReturnError: &error];
    if (crashData == nil) {
        NSLog(@"Could not load crash report: %@", error);
        [crashReporter purgePendingCrashReport];
        return;
    }

    NSString* docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString* filePath = [docPath stringByAppendingPathComponent:@"d.plcrash"];

    [crashData writeToFile:filePath atomically:YES];

    // We could send the report from here, but we'll just print out
    // some debugging info instead
    PLCrashReport *report = [[PLCrashReport alloc] initWithData: crashData error: &error];
    if (report == nil) {
        NSLog(@"Could not parse crash report");
        [crashReporter purgePendingCrashReport];
        return;
    }

    NSLog(@"Crashed on %@", report.systemInfo.timestamp);
    NSLog(@"Crashed with signal %@ (code %@, address=0x%" PRIx64 ")", report.signalInfo.name,
          report.signalInfo.code, report.signalInfo.address);

    NSString *humanText = [PLCrashReportTextFormatter stringValueForCrashReport:report withTextFormat:PLCrashReportTextFormatiOS];

    [[humanText dataUsingEncoding:NSUTF8StringEncoding] writeToFile:[docPath stringByAppendingPathComponent:@"d.crash"] atomically:YES];

    // Purge the report
    [crashReporter purgePendingCrashReport];


    return;
}

然後我們就可以來分析 .crash或者.plcrash檔案了。
具體分析,下面將會介紹。