iOS崩溃日志搜集
开发一款APP用户体验可能显得非常重要,想想要是一款APP老是闪退,bug层出不穷,那得多难受,用户肯定会直接卸载掉的。那么为了开发出更加健壮的程序,我们大致有以下方法:
- 充分考虑系统版本之间的差异
- codeReview(包括代码里面多写些安全代码)
- 崩溃日志搜集,更正
说到日志搜集,可以说现在市面上真的是百花齐放百家争鸣,这里就不一一细说啦,其实apple SDK提供了异常捕获的接口的
自己实现异常统计
typedef void NSUncaughtExceptionHandler(NSException *exception);
FOUNDATION_EXPORT NSUncaughtExceptionHandler * _Nullable NSGetUncaughtExceptionHandler(void);
FOUNDATION_EXPORT void NSSetUncaughtExceptionHandler(NSUncaughtExceptionHandler * _Nullable);
我们自己去定义这个NSUncaughtExceptionHandler就可以在异常的时候做出很多操作了,先自己定义一个类HCDCrashLog
// .h
FOUNDATION_EXPORT void defalutUncaughtExceptionHandler(NSException * exception);
@interface HCDCrashLog : NSObject
+ (void)startWithUncaughtExceptionHandler:(NSUncaughtExceptionHandler *)uncaughtExceptionHandler;
+ (NSUncaughtExceptionHandler *)getUncaughtExceptionHandler;
+ (void)throwException;
@end
//.m
@interface ExceptionInfo : NSObject
@property(readonly) NSString *file;
@property(readonly) int line;
/**
the code causes crash. eg '[myArr objectAtIndex:outRangeIndex]'
*/
@property(readonly) NSString *code;
@end
@implementation ExceptionInfo
@end
ExceptionInfo *getExceptionInfoFromCallStackSymbols(NSArray* callStackSymbols);
void defalutUncaughtExceptionHandler(NSException *exception) {
NSArray *callStackSymbols = [NSThread callStackSymbols];
NSString * reason = [exception reason]; //
NSString * name = [exception name];
NSString * info = [NSString stringWithFormat:@"\n========程序抛出异常========\n\nname:%@\n\nreason:\n%@\n\nuserInfo:\n%@\n\ncallStackSymbols:\n%@",name,reason,[exception userInfo],[callStackSymbols componentsJoinedByString:@"\n"]];
#pragma mark - 能否通过代码的形式去定位崩溃位置....
ExceptionInfo *exceptionInfo = getExceptionInfoFromCallStackSymbols(callStackSymbols);
DLog(@"%@\n=================%@",info,exception.userInfo);
}
ExceptionInfo *getExceptionInfoFromCallStackSymbols(NSArray* callStackSymbols)
{
return nil;
}
@implementation HCDCrashLog
+(void)startWithUncaughtExceptionHandler:(NSUncaughtExceptionHandler *)uncaughtExceptionHandler
{
NSSetUncaughtExceptionHandler(defalutUncaughtExceptionHandler);
}
+(NSUncaughtExceptionHandler *)getUncaughtExceptionHandler
{
return NSGetUncaughtExceptionHandler();
}
+(void)throwException
{
NSException *exception = [NSException exceptionWithName:@"测试的异常" reason:@"人为抛出异常" userInfo:nil];
@throw exception;
}
@end
这样我们就可以在异常的时候将信息传送给服务器或者保存什么的,但是难点在于我们怎么去定位更详细的信息(崩溃的方法、崩溃在哪一行、是什么代码导致崩溃等)源代码在这里,如果有朋友能想到怎么实现的,欢迎指点(好像没办法去做啊,因为dSYM文件在电脑上,我们代码里面只有调用栈信息。另外根据crash文件和dSYM定位请看这里)。 那么既然暂时无法去定位到具体信息,那么我们就要去选择一些三方的平台来统计(大公司大牛多,估计都是自己搞统计)。
Crashlytics崩溃日志统计
说到三方的日志统计,我个人觉得还是Crashlytics最好用,不要问为什么,下面就说一下Crashlytics的方便之处。
Crashlytics使用非常的无脑简单,小白都能轻松集成具体步骤看这里,OC 、swift项目都分得清清楚楚,而且官方还提供了一个Mac APP Fabric帮助用户集成非常方便。上线之后,出现崩溃情况会以邮件的形式发送给你,有木有很开心

邮件里面看起来像这样子
我们需要的信息都有了,还省去我们用crash文件和dSYM去定位的麻烦!赶紧改bug去吧!
另,很好奇大公司怎么做这个,难道用的三方?如果自己做,是怎么从调用栈定位到方法的?可能我想的方向错了吧!