尝试使用Swift进行日志收集-----------失败,最后还是调用OC实现
AppDelegate中
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
CatchCrash.share().installUncaughtExceptionHandler()
return true
}
CatchCrash.swift
import UIKit
private let catchCrash = CatchCrash()
private var UncaughtExceptionCount: Int32 = 0
private var UncaughtExceptionMaximum: Int32 = 10
class CatchCrash: NSObject {
private let UncaughtExceptionMaximum: Int32 = 10
private let SignalHandler: Darwin.sig_t? = { (signal) in
let exceptionInfo = HandleCrash.crash(signal)
try! exceptionInfo?.write(toFile: NSHomeDirectory() + "/Documents/error1.log", atomically: true, encoding: .utf8)
}
class func share() -> CatchCrash {
return catchCrash
}
func installUncaughtExceptionHandler() {
NSSetUncaughtExceptionHandler { (exception) in
// 异常的堆栈信息
let stackArray = exception.callStackSymbols
// 出现异常的原因
let reason = exception.reason
// 异常名称
let name = exception.name
let exceptionInfo = "Eqqqqqxception reason:\(String(describing: reason))\n"
+ "Exception name:\(name)\n"
+ "Exception stack:\(stackArray.description)"
print(exceptionInfo)
var tmpArr = stackArray
tmpArr.insert(reason!, at: 0)
//保存到本地
try! exceptionInfo.write(toFile: NSHomeDirectory() + "/Documents/error1.log", atomically: true, encoding: .utf8)
abort()
}
signal(SIGABRT, SignalHandler)
signal(SIGILL, SignalHandler)
signal(SIGSEGV, SignalHandler)
signal(SIGFPE, SignalHandler)
signal(SIGBUS, SignalHandler)
signal(SIGPIPE, SignalHandler)
}
}
CatchCrash-Bridging-Header.h 中进行桥接
#import "HandleCrash.h"
HandleCrash.h
#import
@interface HandleCrash : NSObject
+ (NSString *)crash:(int)signal;
@end
HandleCrash.m
#import "HandleCrash.h"
#import
#include
NSString * const UncaughtExceptionHandlerSignalExceptionName = @"UncaughtExceptionHandlerSignalExceptionName";
NSString * const UncaughtExceptionHandlerSignalKey = @"UncaughtExceptionHandlerSignalKey";
NSString * const UncaughtExceptionHandlerAddressesKey = @"UncaughtExceptionHandlerAddressesKey";
atomic_int UncaughtExceptionCount = 0;
const int32_t UncaughtExceptionMaximum = 10;
const NSInteger UncaughtExceptionHandlerSkipAddressCount = 4;
const NSInteger UncaughtExceptionHandlerReportAddressCount = 5;
@implementation HandleCrash
+ (NSString *)crash:(int)signal {
int exceptionCount = atomic_fetch_add_explicit(&UncaughtExceptionCount, 1, memory_order_relaxed);
if (exceptionCount > UncaughtExceptionMaximum) {
return @"";
}
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:signal]
forKey:UncaughtExceptionHandlerSignalKey];
NSArray *callStack = [self backtrace];
[userInfo setObject:callStack
forKey:UncaughtExceptionHandlerAddressesKey];
NSException *exception = [NSException
exceptionWithName: UncaughtExceptionHandlerSignalExceptionName reason: [NSString stringWithFormat:
NSLocalizedString(@"Signal %d was raised.", nil),
signal] userInfo: userInfo];
return [NSString stringWithFormat:@"%@, %@, %@", exception.name, exception.reason, exception.userInfo];
}
+ (NSArray *)backtrace
{
void* callstack[128];
int frames = backtrace(callstack, 128);
char **strs = backtrace_symbols(callstack, frames);
int i;
NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
for (
i = UncaughtExceptionHandlerSkipAddressCount;
i < UncaughtExceptionHandlerSkipAddressCount +
UncaughtExceptionHandlerReportAddressCount;
i++)
{
[backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
}
free(strs);
return backtrace;
}
@end