IOS三人行iOS开发攻城狮的集散地iOS Developer

swift搜集崩溃日志

2017-01-06  本文已影响483人  Iam光星人

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.拿到日志之后就可以上传给服务器了,要记的每次上传成功后清除上传的本地文件,这样就完美了。
友情提示:打印需要在崩溃之后的下一次启动才能出现结果!

上一篇下一篇

猜你喜欢

热点阅读