iOS崩溃日志|iOS崩溃日志 收集与发送服务器

iOS开发中我们会遇到程序抛出异常退出的情况,如果是在调试的过程中,异常的信息是一目了然,我们可以很快的定位异常的位置并解决问题。那么当应用已经打包,iPhone设备通过ipa的包安装应用后,在使用过程发现crash,那么如何获取crash日志呢?对于保密性要求不高的程序来说,也可以选择各种一条龙Crash统计产品,如 Crashlytics,Hockeyapp ,友盟,Bugly 等等,不过IOS SDK中提供了一个现成的函数 NSSetUncaughtExceptionHandler 用来做异常处理
利用NSSetUncaughtExceptionHandler,当程序异常退出的时候,可以先进行处理,然后做一些自定义的动作,并通知开发者,是大多数软件都选择的方法。下面就介绍如何在iOS中实现:
首先创建一个MyUncaughtExceptionHandler类 (名字可以自己起)实现崩溃时调用的函数,下面我粘贴我程序中的完整代码,你们需要用的时候可以直接复制就可以.

#import // 崩溃日志 @interface MyUncaughtExceptionHandler : NSObject+ (void)setDefaultHandler; + (NSUncaughtExceptionHandler *)getHandler; + (void)TakeException:(NSException *) exception; end

#import "MyUncaughtExceptionHandler.h" #import "AFNetworking.h" // 沙盒的地址 NSString * applicationDocumentsDirectory() { return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; }// 崩溃时的回调函数 void UncaughtExceptionHandler(NSException * exception) { NSArray * arr = [exception callStackSymbols]; NSString * reason = [exception reason]; // // 崩溃的原因可以有崩溃的原因(数组越界,字典nil,调用未知方法...) 崩溃的控制器以及方法 NSString * name = [exception name]; NSString * url = [NSString stringWithFormat:@"========异常错误报告========\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",name,reason,[arr componentsJoinedByString:@"\n"]]; NSString * path = [applicationDocumentsDirectory() stringByAppendingPathComponent:@"Exception.txt"]; // 将一个txt文件写入沙盒 [url writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil]; }@implementation MyUncaughtExceptionHandler// 沙盒地址 - (NSString *)applicationDocumentsDirectory { return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; }+ (void)setDefaultHandler { NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler); }+ (NSUncaughtExceptionHandler *)getHandler { return NSGetUncaughtExceptionHandler(); }+ (void)TakeException:(NSException *)exception { NSArray * arr = [exception callStackSymbols]; NSString * reason = [exception reason]; NSString * name = [exception name]; NSString * url = [NSString stringWithFormat:@"========异常错误报告========\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",name,reason,[arr componentsJoinedByString:@"\n"];

在appledelegate导入头文件加上一个异常捕获监听,用来处理程序崩溃时的回调动作 在这里也要判断一下之前有没有崩溃日志 如果有发送给服务器
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { #pragma mark -- 崩溃日志 [MyUncaughtExceptionHandler setDefaultHandler]; // 发送崩溃日志 NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *dataPath = [path stringByAppendingPathComponent:@"Exception.txt"]; NSData *data = [NSData dataWithContentsOfFile:dataPath]; if (data != nil) { [self sendExceptionLogWithData:data path:dataPath]; }return YES; }#pragma mark -- 发送崩溃日志 - (void)sendExceptionLogWithData:(NSData *)data path:(NSString *)path {AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.requestSerializer.timeoutInterval = 5.0f; //告诉AFN,支持接受 text/xml 的数据 [AFJSONResponseSerializer serializer].acceptableContentTypes = [NSSet setWithObject:@"text/plain"]; NSString *urlString = @"后台地址"; [manager POST:urlString parameters:nil constructingBodyWithBlock:^(id_Nonnull formData) { [formData appendPartWithFileData:data name:@"file" fileName:@"Exception.txt" mimeType:@"txt"]; } success:^(NSURLSessionDataTask * _Nonnull task, id_Nonnull responseObject) { // 删除文件 NSFileManager *fileManger = [NSFileManager defaultManager]; [fileManger removeItemAtPath:path error:nil]; } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {}];

【iOS崩溃日志|iOS崩溃日志 收集与发送服务器】测试:可以随便建一个控制器 弄一个数组越界测试一下~

    推荐阅读