// // RQUncaughtExceptionHandler.m // TEST // // Created by 张嵘 on 2018/10/22. // Copyright © 2018 张嵘. All rights reserved. // #import "RQUncaughtExceptionHandler.h" #import static NSString *exceptionContent; // 沙盒的地址 NSString * applicationDocumentsDirectory() { return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; } // 崩溃时的回调函数(程序将要crash之前,先执行此方法,此方法执行完毕之后,程序才会崩溃) void UncaughtExceptionHandler(NSException * exception) { NSArray * arr = [exception callStackSymbols]; //异常原因 崩溃的原因 可以有崩溃的原因(数组越界,字典nil,调用未知方法...) 崩溃的控制器以及方法 NSString * reason = [exception reason]; //异常名称 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]; [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationUncaughtException object:nil]; //当前时间 NSDate *date = [NSDate date]; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; NSString *dateString = [formatter stringFromDate:date]; NSString *timeString = dateString; //获取当前设备 NSString *model = [[UIDevice currentDevice] model]; NSString *systemName = [[UIDevice currentDevice] systemName]; NSString *systemVersion = [[UIDevice currentDevice] systemVersion]; //获取应用程序版本号 NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; //获取程序名字 NSString *identifier = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; // \n 换行 exceptionContent = [NSString stringWithFormat:@"\n\n\n =======异常信息========\n时间:%@ \n设备名称:%@ \n设备型号:%@%@ \n当前应用程序版本号:%@ \n应用名称:%@ \n异常名称:%@ \n异常的原因:%@ \nCallStackSymbols:%@",timeString,model,systemName,systemVersion,version,identifier,name,reason,arr]; /**把异常崩溃信息发送至开发者邮件 这里要不要加上网络情况判断 然后在无网络时保存到本地 然后有网在上传?不做了 */ NSMutableString *mailUrl = [NSMutableString string]; [mailUrl appendString:@"mailto:657927212@qq.com"]; [mailUrl appendFormat:@"?cc="]; [mailUrl appendString:@"&subject=程序异常崩溃,请发送异常给程序猿,谢谢合作!"]; [mailUrl appendFormat:@"&body=%@ body!", exceptionContent]; // 打开地址 PS:下面这个方法好像过期 NSString *mailPath = [mailUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; [[UIApplication sharedApplication] openURL:[NSURL URLWithString:mailPath]]; } @implementation RQUncaughtExceptionHandler // 沙盒地址 - (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"]]; NSString * path = [applicationDocumentsDirectory() stringByAppendingPathComponent:@"Exception.txt"]; [url writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil]; } + (NSString *)getCurrentTime { NSDate *date = [NSDate date]; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; NSString *dateString = [formatter stringFromDate:date]; return dateString; } @end