iOS Swift Crash日志收集


嘗試使用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 <Foundation/Foundation.h>

@interface HandleCrash : NSObject

+ (NSString *)crash:(int)signal;

@end

  HandleCrash.m

#import "HandleCrash.h"
#import <stdatomic.h>
#include <execinfo.h>

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM