Objective-C自建崩溃捕获和上传
2016-11-20 本文已影响39人
KenZhangCn
苹果虽然带了崩溃日志的功能,但是估计没几个人会开启允许,普通用户根本就不知道所谓的开发者对自己有什么作用,还会担心安全问题.所有我们还必须对程序进行一些处理,以获取崩溃日志.本篇文章仅获取了系统崩溃日志的打印,没有对内存方面进行进一步分析.
SDK提供了NSSetUncaughtExceptionHandler类,用来获取系统的崩溃日志.我们通过捕获崩溃日志并上传到服务器,可以发现常见的的崩溃问题,特别是在项目紧张,缺少测试时间的时候可以提供很大的帮助.
通过定义UncaughtExceptionHandler类来捕获并记录崩溃日志.
#import "UncaughtExceptionHandler.h"
NSString *applicationDocumentsDirectory() {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
void UncaughtExceptionHandler(NSException *exception) {
NSArray *arr = [exception callStackSymbols];
NSString *reason = [exception reason];
NSString *name = [exception name];
NSString *baseMessage = [NSString stringWithFormat:@"IDENTIFIER_NUMBER: %@\n OSVERSION: %@\n PHONE_TYPE: %@\n APP_VERSION: %@", IDENTIFIER_NUMBER, PHONE_VERSION, PHONE_TYPE, APP_VERSION];
NSString *url = [NSString stringWithFormat:@"=============Crash Log=============\n%@\nname:\n%@\nreason:\n%@\ncallStackSymbols:\n%@", baseMessage,
name,reason,[arr componentsJoinedByString:@"\n"]];
NSString *path = [applicationDocumentsDirectory() stringByAppendingPathComponent:@"Exception.txt"];
[url writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];
}
@implementation BPBUncaughtExceptionHandler
- (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
+ (void)setDefaultHandler {
NSSetUncaughtExceptionHandler (&UncaughtExceptionHandler);
}
@end
然后我们需要再定义一个CrashHandler类来将捕获的崩溃日志上传到后台的服务器.上传完成之后再删除文件.
#import "CrashHandler.h"
@implementation BPBCrashHandler
+ (void)uploadCrashLog {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"Exception.txt"];
NSString *str = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
if (str) {
[ServerReqestUtils uploadCrashLogWithContent:str callBack:^(id obj) {
float code = [obj[@"code"] floatValue];
if (code == 1000) {
NSLog(@"上传成功!");
[fileManager removeItemAtPath:filePath error:nil];
}
}];
}
}
@end
最后只需要在didFinishLaunchingWithOptions方法内执行这两个方法就可以捕获崩溃日志了.
[UncaughtExceptionHandler setDefaultHandler];
[CrashHandler uploadCrashLog];
文章整理参考网络文章,如有错误,欢迎讨论指出。