在做崩潰日志收集與上傳的時候用OC寫了一個demo可以正常工作(OC版本的資料網上很多,這里不贅述),于是想采用現成的demo進行OC與Swift將模塊集成到Swift項目,不過集成完畢后不管如何程序始終不會走異常監聽的回調,因此無法將崩潰信息保存到本地,后來在同事推薦的一篇文章中找到了用Swift寫的崩潰日志收集demo,文章鏈接:http://www.th7.cn/Program/IOS/201701/1086561.shtml ,看完后深受啟發,將代碼封裝了一下,在需要使用的時候直接將下面的代碼復制,在上傳方法中添加服務器地址并導入第三方庫AFNetworking即可使用:
import UIKit
import AFNetworking
class TBUncaughtExceptionHandler: NSObject {
static let shared = TBUncaughtExceptionHandler()
fileprivate override init() {
}
public func exceptionLogWithData() {
setDefaultHandler()
let path = getdataPath()
// print(path)
let data = NSData.init(contentsOfFile: path)
if data != nil {
// let crushStr = String.init(data: data! as Data, encoding: String.Encoding.utf8)
// print(crushStr!)
//上傳數據
sendExceptionLogWithData(data: data! as Data, path: path)
}
//測試數據
// let arry:NSArray = ["1"]
// print("%@",arry[5])
}
///沙盒路徑
fileprivate func getdataPath() -> String{
let str = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last!
let urlPath = str.appending("/Exception.txt")
return urlPath
}
///異?;卣{
fileprivate 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{}
}
}
///上傳
fileprivate func sendExceptionLogWithData(data:Data,path:String){
let manager = AFHTTPSessionManager()
manager.requestSerializer.timeoutInterval = 5.0
AFJSONResponseSerializer().acceptableContentTypes = NSSet(object: "text/plain") as? Set<String>
manager.post("服務器地址", parameters: nil, constructingBodyWith: { (formData) in
formData.appendPart(withFileData: data, name: "file", fileName: "Exception.txt", mimeType: "txt")
}, progress: nil, success: { (task, responseObject) in
let fileManger = FileManager.default
do {
try fileManger.removeItem(atPath: path)
}catch{
}
}) { (task, error) in
//上傳失敗
print(error)
}
}
}
使用方法:在AppDelegate中
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
TBUncaughtExceptionHandler.shared.exceptionLogWithData()
return true
}