使用NSSetUncaughtExceptionHandler捕
2023-02-14 本文已影响0人
江湖闹士
iOS获取异常的方式有多种,利用第三方bugly,友盟等,苹果自己也提供的有API --> NSSetUncaughtExceptionHandler
1、创建一个捕获异常的类CustomUncaughtExceptionHandler
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface CustomUncaughtExceptionHandler : NSObject
+ (void)setDefaultHandler;
+ (NSUncaughtExceptionHandler *)getHandler;
@end
NS_ASSUME_NONNULL_END
#import "CustomUncaughtExceptionHandler.h"
@implementation CustomUncaughtExceptionHandler
//沙盒地址
NSString *applicationDocumentsDirectory() {
return NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
}
//捕获到异常,先保存到本地
void UncaughtExceptionHandler(NSException *exception) {
NSLog(@"%@",exception);
NSArray *arr = [exception callStackSymbols];
NSLog(@"%@",arr);
NSString *name = exception.name;
NSString *reason = exception.reason;
NSString *url = [NSString stringWithFormat:@"crash报告\nname:%@\nreason:%@\n堆栈信息:%@",name,reason,[arr componentsJoinedByString:@"\n"]];
NSString *path = [applicationDocumentsDirectory() stringByAppendingPathComponent:@"crash.log"];
NSLog(@"%@",path);
[url writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];
}
+ (void)setDefaultHandler{
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
}
+ (NSUncaughtExceptionHandler *)getHandler {
return NSGetUncaughtExceptionHandler();
}
@end
截屏2023-02-15 20.19.35.png
保存的堆栈信息内容
2、在AppDelegate中调用setDefaultHandler方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[CustomUncaughtExceptionHandler setDefaultHandler];
//获取崩溃日志,然后发送
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *dataPath = [path stringByAppendingPathComponent:@"crash.log"];
NSData *data = [NSData dataWithContentsOfFile:dataPath];
if (data != nil) {
//发送崩溃日志
NSLog(@"crash了:%@",data);
//上传服务器操作后,把本地文件删除
NSFileManager *manger = [NSFileManager defaultManager];
BOOL isDelete = [manger removeItemAtPath:path error:nil];
if (isDelete) {
NSLog(@"删除成功!");
}else{
NSLog(@"删除失败!");
}
}
return YES;
}