首先介绍一款工具 定位解析信号异常上github上搜索DSYMTools,和邮件发送SKPSMTPMessage
配上
1.解决普通和信号异常
直接使用先上代码
.h文件
#import
#import
@interfaceUncaughtExceptionHandler :NSObject{
BOOLdismissed;
}
@end
voidHandleException(NSException*exception);
voidSignalHandler(intsignal);
voidInstallUncaughtExceptionHandler(void);
.m文件
#import"UncaughtExceptionHandler.h"
#include
#include
#import"SKPSMTPMessage.h"
#import"NSData+Base64Additions.h"
NSString*constUncaughtExceptionHandlerSignalExceptionName =@"UncaughtExceptionHandlerSignalExceptionName";
NSString*constUncaughtExceptionHandlerSignalKey =@"UncaughtExceptionHandlerSignalKey";
NSString*constUncaughtExceptionHandlerAddressesKey =@"UncaughtExceptionHandlerAddressesKey";
NSString*constUncaughtExceptionHandlerStackSysbolsArrayKey =@"UncaughtExceptionHandlerStackSysbolsArrayKey";
volatileint32_tUncaughtExceptionCount =0;
constint32_tUncaughtExceptionMaximum =20;
constNSIntegerUncaughtExceptionHandlerSkipAddressCount =0;
constNSIntegerUncaughtExceptionHandlerReportAddressCount =20;
@interfaceUncaughtExceptionHandler()
/**网络请求管理者*/
@property(strong,nonatomic)YLTHTTPSessionManager*manager;
@end
@implementationUncaughtExceptionHandler
+ (NSArray*)backtrace {
void* callstack[128];
intframes =backtrace(callstack,128);
char**strs =backtrace_symbols(callstack, frames);
inti;
NSMutableArray*backtrace = [NSMutableArrayarrayWithCapacity:frames];
for(i =UncaughtExceptionHandlerSkipAddressCount; i
[backtraceaddObject:[NSStringstringWithUTF8String:strs[i]]];
}
free(strs);
returnbacktrace;
}
- (void)alertView:(UIAlertView*)anAlertView clickedButtonAtIndex:(NSInteger)anIndex {
if(anIndex ==0){
dismissed=YES;
}elseif(anIndex==1) {
NSLog(@"异常!!!");
}
}
#pragma mark -上传crash日志
- (void)validateAndSaveCriticalApplicationDataWithException:(NSException*)exception {
//发送crash到邮箱
[selfmessageEmailWithException:exception];
//发送crash到服务器
//[self messageServerithException:exception];
}
#pragma mark - <发送给后台服务器------------------------------------------>
- (void)messageServerithException:(NSException*)exception {
//应用版本
NSString*version =AppVersion;
if(nil== version) {
version =@"";
}
//设备版本
NSString*deviceModel = [PublicMethodiphoneType];
//系统版本
NSString*sysVersion = [UIDevicecurrentDevice].systemVersion;
//邮件主题
NSString*subject = [NSStringstringWithFormat:@"[Crash][iOS][%@][%@][%@]", version, sysVersion, deviceModel];
//调用栈
NSArray*stackSysbolsArray = [[exceptionuserInfo]objectForKey:UncaughtExceptionHandlerAddressesKey];
//崩溃原因
NSString*reason = [exceptionreason];
//崩溃原因
NSString*name = [exceptionname];
NSString*encryptDate = [PublicMethodencryptAESDataWithJSON];
NSMutableDictionary*dict = [NSMutableDictionarydictionary];
//上传服务器接口
[self.managerPOST:@"https://passport.zgylt.com/Data/CollectionException"parameters:dictprogress:nilsuccess:^(NSURLSessionDataTask*_Nonnulltask,id_NullableresponseObject) {
if([responseObject[@"Code"]isEqualToString:@"200"]) {
NSLog(@"发送成功");
}else{
NSLog(@"发送失败");
}
}failure:^(NSURLSessionDataTask*_Nullabletask,NSError*_Nonnullerror) {
NSLog(@"发送失败%@",error);
}];
}
/**网络请求管理者*/
- (YLTHTTPSessionManager*)manager {
if(!_manager) {
_manager= [YLTHTTPSessionManagermanager];
}
return_manager;
}
#pragma mark - <发送邮件------------------------------------------>
- (void)messageEmailWithException:(NSException*)exception {
//应用版本
NSString*version =AppVersion;
if(nil== version) {
version =@"";
}
//设备版本
NSString*deviceModel = [PublicMethodiphoneType];
//系统版本
NSString*sysVersion = [UIDevicecurrentDevice].systemVersion;
//邮件主题
NSString*subject = [NSStringstringWithFormat:@"[Crash][iOS][%@][%@][%@]", version, sysVersion, deviceModel];
//调用栈
NSArray*stackSysbolsArray = [[exceptionuserInfo]objectForKey:UncaughtExceptionHandlerAddressesKey];
//崩溃原因
NSString*reason = [exceptionreason];
//崩溃原因
NSString*name = [exceptionname];
//邮件正文
NSString*body = [NSStringstringWithFormat:@"\n----------------------------------------------------\n当你看到这个页面的时候别慌,简单的描述下刚才的操作,然后邮件我\n\n----------------------------------------------------\n崩溃标识:\n\n%@\n----------------------------------------------------\n崩溃原因:\n\n%@\n----------------------------------------------------\n崩溃详情:\n\n%@\n",
name,
reason,
[stackSysbolsArraycomponentsJoinedByString:@"\n"]];
SKPSMTPMessage*myMessage = [[SKPSMTPMessagealloc]init];
发件箱
myMessage.fromEmail=@"xxx@163.com";
收件箱
myMessage.toEmail=@"xxxx@qq.com";
抄送
myMessage.bccEmail=@"xxxxx@qq.com";
发件箱的服务器主机地址
myMessage.relayHost=@"smtp.163.com";
myMessage.requiresAuth=YES;
if(myMessage.requiresAuth) {
// 发件箱
myMessage.login=@"xxx@163.com";
// 发件箱的POT/SMT/..的密码,必须要去授权获取这个密码,不然用不了邮件发送功能
myMessage.pass=@"xxxx";
}
myMessage.wantsSecure=YES;//为gmail邮箱设置smtp.gmail.com
myMessage.subject= subject;
myMessage.delegate=self;
//设置邮件内容
NSDictionary*plainPart = [NSDictionarydictionaryWithObjectsAndKeys:@"text/plain; charset=UTF-8",kSKPSMTPPartContentTypeKey,
body,kSKPSMTPPartMessageKey,@"8bit",kSKPSMTPPartContentTransferEncodingKey,nil];
myMessage.parts= [NSArrayarrayWithObjects:plainPart,nil];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
[myMessagesend];
});
}
- (void)handleException:(NSException*)exception {
[selfvalidateAndSaveCriticalApplicationDataWithException:exception];
NSString*message = [NSStringstringWithFormat:NSLocalizedString(@"如果点击继续,程序有可能会出现其他的问题,建议您还是点击退出按钮并重新打开\n\n"@"异常原因如下:\n%@\n%@",nil),[exceptionreason],[[exceptionuserInfo]objectForKey:UncaughtExceptionHandlerAddressesKey]];
UIAlertView*alert =[[UIAlertViewalloc]initWithTitle:NSLocalizedString(@"抱歉,程序出现了异常",nil)
message:message
delegate:self
cancelButtonTitle:NSLocalizedString(@"退出",nil)
otherButtonTitles:NSLocalizedString(@"继续",nil),nil];
[alertshow];
CFRunLoopRefrunLoop =CFRunLoopGetCurrent();
CFArrayRefallModes =CFRunLoopCopyAllModes(runLoop);
while(!dismissed) {
for(NSString*modein(__bridgeNSArray*)allModes) {
CFRunLoopRunInMode((__bridgeCFStringRef)mode,0.001,false);
}
}
CFRelease(allModes);
NSSetUncaughtExceptionHandler(NULL);
signal(SIGABRT,SIG_DFL);
signal(SIGILL,SIG_DFL);
signal(SIGSEGV,SIG_DFL);
signal(SIGFPE,SIG_DFL);
signal(SIGBUS,SIG_DFL);
signal(SIGPIPE,SIG_DFL);
if([[exceptionname]isEqual:UncaughtExceptionHandlerSignalExceptionName]) {
kill(getpid(), [[[exceptionuserInfo]objectForKey:UncaughtExceptionHandlerSignalKey]intValue]);
}else{
[exceptionraise];
}
}
- (void)messageSent:(SKPSMTPMessage*)message
{
NSLog(@"恭喜,邮件发送成功");
}
- (void)messageFailed:(SKPSMTPMessage*)message error:(NSError*)error
{
NSLog(@"不好意思,邮件发送失败");
}
@end
voidHandleException(NSException*exception) {
int32_texceptionCount =OSAtomicIncrement32(&UncaughtExceptionCount);
if(exceptionCount >UncaughtExceptionMaximum) {
return;
}
//调用栈
NSArray*stackSysbolsArray = [exceptioncallStackSymbols];
NSMutableDictionary*userInfo =[NSMutableDictionarydictionaryWithDictionary:[exceptionuserInfo]];
[userInfosetObject:[NSArrayarrayWithArray:stackSysbolsArray]forKey:UncaughtExceptionHandlerAddressesKey];
[[[UncaughtExceptionHandleralloc]init]performSelectorOnMainThread:@selector(handleException:)withObject:
[NSExceptionexceptionWithName:[exceptionname]reason:[exceptionreason]userInfo:userInfo]waitUntilDone:YES];
}
voidSignalHandler(intsignal) {
int32_texceptionCount =OSAtomicIncrement32(&UncaughtExceptionCount);
if(exceptionCount >UncaughtExceptionMaximum) {
return;
}
NSMutableDictionary*userInfo =[NSMutableDictionarydictionaryWithObject:[NSNumbernumberWithInt:signal]forKey:UncaughtExceptionHandlerSignalKey];
NSArray*callStack = [UncaughtExceptionHandlerbacktrace];
[userInfosetObject:callStackforKey:UncaughtExceptionHandlerAddressesKey];
[[[UncaughtExceptionHandleralloc]init]performSelectorOnMainThread:@selector(handleException:)
withObject:[NSExceptionexceptionWithName:UncaughtExceptionHandlerSignalExceptionName
reason:[NSStringstringWithFormat:NSLocalizedString(@"Signal %d was raised.",nil),signal]userInfo:userInfo]
waitUntilDone:YES];
}
voidInstallUncaughtExceptionHandler(void) {
NSSetUncaughtExceptionHandler(&HandleException);
signal(SIGABRT,SignalHandler);
signal(SIGILL,SignalHandler);
signal(SIGSEGV,SignalHandler);
signal(SIGFPE,SignalHandler);
signal(SIGBUS,SignalHandler);
signal(SIGPIPE,SignalHandler);
}
邮件处理
http://blog.csdn.net/u010218226/article/details/53114595
http://blog.csdn.net/aldridge1/article/details/38826035
http://blog.csdn.net/aldridge1/article/details/38826035