iOS开发中我们会遇到程序抛出异常退出的情况,如果是在调试的过程中,异常的信息是一目了然,我们可以很快的定位异常的位置并解决问题。那么当应用已经打包,iPhone设备通过ipa的包安装应用后,在使用过程发现crash,那么如何获取crash日志呢?对于保密性要求不高的程序来说,也可以选择各种一条龙Crash统计产品,如 Crashlytics,Hockeyapp ,友盟,Bugly 等等,不过IOS SDK中提供了一个现成的函数 NSSetUncaughtExceptionHandler 用来做异常处理
利用NSSetUncaughtExceptionHandler,当程序异常退出的时候,可以先进行处理,然后做一些自定义的动作,并通知开发者,是大多数软件都选择的方法。下面就介绍如何在iOS中实现:
1.oc的实现:
// 崩溃时的回调函数
void UncaughtExceptionHandler(NSException * exception) {
NSArray * arr = [exception callStackSymbols];
NSString * reason = [exception reason]; // // 崩溃的原因 可以有崩溃的原因(数组越界,字典nil,调用未知方法...) 崩溃的控制器以及方法
NSString * name = [exception name];
NSDate *currentDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"YYYY/MM/dd hh:mm:ss SS"];
NSString *dateString = [dateFormatter stringFromDate:currentDate];
NSString * url = [NSString stringWithFormat:@"========异常错误报告========\ntime:%@\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",dateString,name,reason,[arr componentsJoinedByString:@"\n"]];
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString * path = [documentPath stringByAppendingPathComponent:@"Exception.txt"];
// 将一个txt文件写入沙盒
[url writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];
}
// 沙盒地址
- (NSString *)dataPath {
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString * path = [documentPath stringByAppendingPathComponent:@"Exception.txt"];
return path;
}
2.swift的实现
public func getdataPath() -> String{
let str = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last!
let urlPath = str.appending("Exception.txt")
return urlPath
}
public func setDefaultHandler() {
NSSetUncaughtExceptionHandler { (exception) in
let arr:NSArray = exception.callStackSymbols as NSArray
let reason:String = exception.reason!
let name:String = exception.name.rawValue
let date:NSDate = NSDate()
let timeFormatter = DateFormatter()
timeFormatter.dateFormat = "YYYY/MM/dd hh:mm:ss SS"
let strNowTime = timeFormatter.string(from: date as Date) as String
let url:String = String.init(format: "========异常错误报告========\ntime:%@\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",strNowTime,name,reason,arr.componentsJoined(by: "\n"))
let documentpath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last!
let path = documentpath.appending("Exception.txt")
do{
try
url.write(toFile: path, atomically: true, encoding: String.Encoding.utf8)
}catch{}
}
}
到这里实现已经完成,别告诉我你不会调用.......,好吧我还是给出例子以便大家可以粘贴复制,哈哈。
3.调用方法
这里只给出swift的实例,相信大家一看便知
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
exceptionLogWithData()
return true
}
func exceptionLogWithData() {
CDUncaughtExceptionHandle.shared.setDefaultHandler()
let str = CDUncaughtExceptionHandle.shared.getdataPath()
let data = NSData.init(contentsOfFile: str)
if data != nil {
let crushStr = String.init(data: data as! Data, encoding: String.Encoding.utf8)
print(crushStr!)
}
//测试数据
let arry:NSArray = ["1"]
print("%@",arry[5])
}
4.拿到日志之后就可以上传给服务器了,要记的每次上传成功后清除上传的本地文件,这样就完美了。
友情提示:打印需要在崩溃之后的下一次启动才能出现结果!
网友评论