RQUncaughtExceptionHandler.m 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. //
  2. // RQUncaughtExceptionHandler.m
  3. // TEST
  4. //
  5. // Created by 张嵘 on 2018/10/22.
  6. // Copyright © 2018 张嵘. All rights reserved.
  7. //
  8. #import "RQUncaughtExceptionHandler.h"
  9. #import <UIKit/UIKit.h>
  10. static NSString *exceptionContent;
  11. // 沙盒的地址
  12. NSString * applicationDocumentsDirectory() {
  13. return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
  14. }
  15. // 崩溃时的回调函数(程序将要crash之前,先执行此方法,此方法执行完毕之后,程序才会崩溃)
  16. void UncaughtExceptionHandler(NSException * exception) {
  17. NSArray * arr = [exception callStackSymbols];
  18. //异常原因 崩溃的原因 可以有崩溃的原因(数组越界,字典nil,调用未知方法...) 崩溃的控制器以及方法
  19. NSString * reason = [exception reason];
  20. //异常名称
  21. NSString * name = [exception name];
  22. NSString * url = [NSString stringWithFormat:@"========异常错误报告========\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",name,reason,[arr componentsJoinedByString:@"\n"]];
  23. NSString * path = [applicationDocumentsDirectory() stringByAppendingPathComponent:@"Exception.txt"];
  24. // 将一个txt文件写入沙盒
  25. [url writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];
  26. [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationUncaughtException object:nil];
  27. //当前时间
  28. NSDate *date = [NSDate date];
  29. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  30. [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  31. NSString *dateString = [formatter stringFromDate:date];
  32. NSString *timeString = dateString;
  33. //获取当前设备
  34. NSString *model = [[UIDevice currentDevice] model];
  35. NSString *systemName = [[UIDevice currentDevice] systemName];
  36. NSString *systemVersion = [[UIDevice currentDevice] systemVersion];
  37. //获取应用程序版本号
  38. NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
  39. //获取程序名字
  40. NSString *identifier = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
  41. // \n 换行
  42. exceptionContent = [NSString stringWithFormat:@"\n\n\n =======异常信息========\n时间:%@ \n设备名称:%@ \n设备型号:%@%@ \n当前应用程序版本号:%@ \n应用名称:%@ \n异常名称:%@ \n异常的原因:%@ \nCallStackSymbols:%@",timeString,model,systemName,systemVersion,version,identifier,name,reason,arr];
  43. /**把异常崩溃信息发送至开发者邮件
  44. 这里要不要加上网络情况判断 然后在无网络时保存到本地 然后有网在上传?不做了
  45. */
  46. NSMutableString *mailUrl = [NSMutableString string];
  47. [mailUrl appendString:@"mailto:657927212@qq.com"];
  48. [mailUrl appendFormat:@"?cc="];
  49. [mailUrl appendString:@"&subject=程序异常崩溃,请发送异常给程序猿,谢谢合作!"];
  50. [mailUrl appendFormat:@"&body=<b>%@</b> body!", exceptionContent];
  51. // 打开地址 PS:下面这个方法好像过期
  52. NSString *mailPath = [mailUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  53. [[UIApplication sharedApplication] openURL:[NSURL URLWithString:mailPath]];
  54. }
  55. @implementation RQUncaughtExceptionHandler
  56. // 沙盒地址
  57. - (NSString *)applicationDocumentsDirectory {
  58. return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
  59. }
  60. + (void)setDefaultHandler {
  61. NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
  62. }
  63. + (NSUncaughtExceptionHandler *)getHandler {
  64. return NSGetUncaughtExceptionHandler();
  65. }
  66. + (void)TakeException:(NSException *)exception {
  67. NSArray * arr = [exception callStackSymbols];
  68. NSString * reason = [exception reason];
  69. NSString * name = [exception name];
  70. NSString * url = [NSString stringWithFormat:@"========异常错误报告========\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",name,reason,[arr componentsJoinedByString:@"\n"]];
  71. NSString * path = [applicationDocumentsDirectory() stringByAppendingPathComponent:@"Exception.txt"];
  72. [url writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];
  73. }
  74. + (NSString *)getCurrentTime {
  75. NSDate *date = [NSDate date];
  76. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  77. [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  78. NSString *dateString = [formatter stringFromDate:date];
  79. return dateString;
  80. }
  81. @end