使用NSException归档崩溃信息并上传服务器
- 当app在即将崩溃的时候,我们可以通过NSException来记录导致程序崩溃的原因.
- 首先,创建一个CrashManager类来管理当前app的崩溃信息
.h文件中
/**崩溃类型 */
@property (nonatomic,strong) NSString *name;
/**崩溃原因 */
@property (nonatomic,strong) NSString *reason;
/**栈信息 */
@property (nonatomic,strong) NSString *className;
/**根据需要选择需不需要创建单例*/
+ (instancetype)shareCrashManager;
/**保存*/
+ (void)save:(CrashManager *)manager;
/**读取*/
+ (void)read:(void (^)(BOOL,CrashManager *))block;
/**上传服务器*/
+ (void)postServer:(CrashManager *)manager;
当然,要添加NSCoding;
.m文件中
#define CrashFilePath [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"CrashManager.data"]
@implementation CrashManager
static CrashManager * _instance = nil;
+ (instancetype)shareCrashManager
{
return _instance;
}
+(void)load
{
_instance = [[self alloc] init];
}
+ (instancetype)alloc
{
if (_instance) {
@throw [NSException exceptionWithName:@"NSInternalInconsistencyException" reason:@"There can only be one Person instance." userInfo:nil];
}
return [super alloc];
}
+ (void)save:(CrashManager *)manager
{
[NSKeyedArchiver archiveRootObject:manager toFile:CrashFilePath];
}
+ (void)read:(void (^)(BOOL,CrashManager *))block
{
CrashManager * manager =(CrashManager *)[NSKeyedUnarchiver unarchiveObjectWithFile:CrashFilePath];
if ([manager.name isEqualToString:@"(null)"] || manager.name == nil) {
block(NO,manager);
}else block(YES,manager);
}
+ (void)postServer:(CrashManager *)manager
{
//上传
NSLog(@"上传服务器");
//上传成功后删除本地文件
NSFileManager * fileManager =[NSFileManager defaultManager];
BOOL existsFile = [fileManager fileExistsAtPath:CrashFilePath];
if (existsFile) {
[fileManager removeItemAtPath:CrashFilePath error:nil];
}
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeObject:_reason forKey:@"reason"];
[aCoder encodeObject:_className forKey:@"className"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
_name = [aDecoder decodeObjectForKey:@"name"];
_reason = [aDecoder decodeObjectForKey:@"reason"];
_className = [aDecoder decodeObjectForKey:@"className"];
}
return self;
}
这样,用来管理崩溃信息的Model就创建完成
然后在AppDelegate中添加NSException;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSSetUncaughtExceptionHandler(&handler);
[CrashManager read:^(BOOL success, CrashManager *manager) {
if (success) {
NSLog(@"crash:===%@",manager.name);
[CrashManager postServer:manager];
}else{
NSLog(@"no crash");
}
}];
return YES;
}
void handler(NSException * exception){
NSArray * arr = [exception callStackSymbols];
NSString * reason = [exception reason];
NSString * name = [exception name];
CrashManager * manager = [CrashManager shareCrashManager];
manager.name = name;
manager.className = arr[3];
manager.reason = reason;
[CrashManager save:manager];
}
这样就完成了,总体思路是程序在即将崩溃的时候讲崩溃信息归档到cache文件中,然后在程序下一次启动的时候将cache中的data文件传到服务器并删除.
网友评论