IOS異常日誌記錄與展現功能

來源:互聯網
上載者:User

標籤:

在平常的APP開發過程中經常碰到程式遇到異常閃退的問題,通過日誌可以把相關的詳細錯誤資訊進行記錄,本執行個體要記錄不管在哪個頁面出錯都要進行記錄,這邊使用到的日誌記錄外掛程式CocoaLumberjack,以文本的形式記錄錯誤資訊,然後再去讀取各個文本的內容進行展示;當然現在有很多第三方的外掛程式比如友盟也已經整合錯誤記錄的功能;

如下:

1:封裝DDLogger的類

MyFileLogger.h檔案#import <Foundation/Foundation.h>#import <CocoaLumberjack.h>@interface MyFileLogger : NSObject@property (nonatomic, strong, readwrite) DDFileLogger *fileLogger;+(MyFileLogger *)sharedManager;@end
MyFileLogger.m檔案#import "MyFileLogger.h"@implementation MyFileLogger#pragma mark - Inititlization- (instancetype)init{    self = [super init];        if (self) {        [self configureLogging];    }    return self;}#pragma mark 單例模式static MyFileLogger *sharedManager=nil;+(MyFileLogger *)sharedManager{    static dispatch_once_t once;    dispatch_once(&once, ^{        sharedManager=[[self alloc]init];    });    return sharedManager;}#pragma mark - 配記日誌類型- (void)configureLogging{#ifdef DEBUG    [DDLog addLogger:[DDASLLogger sharedInstance]];    [DDLog addLogger:[DDTTYLogger sharedInstance]];#endif    [DDLog addLogger:self.fileLogger];}#pragma mark - 初始設定檔案記錄類型- (DDFileLogger *)fileLogger{    if (!_fileLogger) {        DDFileLogger *fileLogger = [[DDFileLogger alloc] init];        fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling        fileLogger.logFileManager.maximumNumberOfLogFiles = 7;                _fileLogger = fileLogger;    }        return _fileLogger;}@end

這邊是設定24小時進行記錄一個檔案

2:出進異常進行記錄

MyExceptionHandler.h檔案#import <Foundation/Foundation.h>#import <CocoaLumberjack.h>@interface MyExceptionHandler : NSObject+ (void)setDefaultHandler;+ (NSUncaughtExceptionHandler *)getHandler;+ (void)TakeException:(NSException *) exception;@end
#import "MyExceptionHandler.h"void UncaughtExceptionHandler(NSException * exception){    NSArray * arr = [exception callStackSymbols];    NSString * reason = [exception reason];    NSString * name = [exception name];    NSString * url = [NSString stringWithFormat:@"========異常錯誤報表========\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",name,reason,[arr componentsJoinedByString:@"\n"]];    DDLogError(@"%@\n\n",url);}@implementation MyExceptionHandler+ (void)setDefaultHandler{    NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);}+ (NSUncaughtExceptionHandler *)getHandler{    return NSGetUncaughtExceptionHandler();}+ (void)TakeException:(NSException *)exception{    NSArray * arr = [exception callStackSymbols];    NSString * reason = [exception reason];    NSString * name = [exception name];    NSString * url = [NSString stringWithFormat:@"========異常錯誤報表========\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",name,reason,[arr componentsJoinedByString:@"\n"]];    DDLogError(@"%@",url);}@end

這個檔案也是當出現異常會執行

3:AppDelegate配置的內容

AppDelegate.h檔案內容#import <UIKit/UIKit.h>#import <DDLog.h>#import <CocoaLumberjack.h>#import "MyExceptionHandler.h"#import "MyFileLogger.h"@interface AppDelegate : UIResponder <UIApplicationDelegate>@property (strong, nonatomic) UIWindow *window;@property (nonatomic, strong) MyFileLogger *logger;@end
AppDelegate.m檔案:#import "AppDelegate.h"@interface AppDelegate ()@end@implementation AppDelegatestatic const int ddLogLevel = LOG_LEVEL_VERBOSE;- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    //初始化    [MyExceptionHandler setDefaultHandler];    self.logger=[[MyFileLogger alloc]init];        NSString *path = NSHomeDirectory();//主目錄    NSLog(@"當前項目的路徑:%@",path);        return YES;}- (void)applicationWillResignActive:(UIApplication *)application {}- (void)applicationDidEnterBackground:(UIApplication *)application {}- (void)applicationWillEnterForeground:(UIApplication *)application {}- (void)applicationDidBecomeActive:(UIApplication *)application {}- (void)applicationWillTerminate:(UIApplication *)application {}@end

這邊重點是設定DDLOG的記錄等級ddLogLevel,以及上面兩個檔案的初始化[MyExceptionHandler setDefaultHandler];self.logger=[[MyFileLogger alloc]init];

實現上面的代碼已經能夠記錄異常的內容;

4:建立一個錯誤的異常代碼

- (void)viewDidLoad {    [super viewDidLoad];        NSArray *[email protected][@"123",@"444"];    id testID=test[5];}

執行到這段代碼便記錄異常的內容,接著進行內容的展示,是以一個列表展示每個記錄檔,然後一個詳細頁面進行展示;

5:日誌列表

loggerTableViewController.h檔案#import <UIKit/UIKit.h>#import <CocoaLumberjack.h>#import "AppDelegate.h"#import "LoggerDetailViewController.h"@interface loggerTableViewController : UIViewController@end
#import "loggerTableViewController.h"#define BLSRecyclingRecordViewController_CellIdentifier @"MyTablecell"@interface loggerTableViewController ()<UITableViewDataSource, UITableViewDelegate>@property (strong, nonatomic) UITableView *myTableView;@property (nonatomic, strong) NSDateFormatter *dateFormatter;@property (nonatomic, weak) DDFileLogger *fileLogger;@property (nonatomic, strong) NSArray *logFiles;@end@implementation loggerTableViewController- (void)viewDidLoad {    [super viewDidLoad];        //載入記錄檔    AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];    _fileLogger = delegate.logger.fileLogger;        [self loadLogFiles];        if (!_myTableView) {        _myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height) style:UITableViewStyleGrouped];        _myTableView.showsVerticalScrollIndicator = NO;        _myTableView.showsHorizontalScrollIndicator=NO;        _myTableView.dataSource = self;        _myTableView.delegate = self;        [_myTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:BLSRecyclingRecordViewController_CellIdentifier];        [self.view addSubview:_myTableView];    }}//讀取日誌的檔案個數- (void)loadLogFiles{    self.logFiles = self.fileLogger.logFileManager.sortedLogFileInfos;}//時間格式- (NSDateFormatter *)dateFormatter{    if (_dateFormatter) {        return _dateFormatter;    }    _dateFormatter = [[NSDateFormatter alloc] init];    [_dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];    return _dateFormatter;}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];}#pragma mark - Table view data source- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{    if (section==0) {        return 40;    }    return 10;}- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{    return 1;}- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{    return 2;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    if (section == 0) {        return self.logFiles.count;    }        return 1;}- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{    UIView *headView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, 30)];    if (section==0) {        UILabel *myLabel=[[UILabel alloc]initWithFrame:CGRectMake(10, 10, [[UIScreen mainScreen] bounds].size.width, 30)];        [email protected]"日記列表";        [headView addSubview:myLabel];    }        return headView;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:BLSRecyclingRecordViewController_CellIdentifier];    if (indexPath.section == 0) {        DDLogFileInfo *logFileInfo = (DDLogFileInfo *)self.logFiles[indexPath.row];        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;        cell.textLabel.text = indexPath.row == 0 ? NSLocalizedString(@"當前", @"") : [self.dateFormatter stringFromDate:logFileInfo.creationDate];        cell.textLabel.textAlignment = NSTextAlignmentLeft;    } else {        cell.accessoryType = UITableViewCellAccessoryNone;        cell.textLabel.textAlignment = NSTextAlignmentCenter;        cell.textLabel.text = NSLocalizedString(@"清理舊的記錄", @"");    }    return cell;}#pragma mark - Table view delegate- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{    [tableView deselectRowAtIndexPath:indexPath animated:YES];        if (indexPath.section == 0) {        DDLogFileInfo *logFileInfo = (DDLogFileInfo *)self.logFiles[indexPath.row];        NSData *logData = [NSData dataWithContentsOfFile:logFileInfo.filePath];        NSString *logText = [[NSString alloc] initWithData:logData encoding:NSUTF8StringEncoding];                LoggerDetailViewController *detailViewController = [[LoggerDetailViewController alloc] initWithLog:logText                                                                                                       forDateString:[self.dateFormatter stringFromDate:logFileInfo.creationDate]];        [self.navigationController pushViewController:detailViewController animated:YES];    } else {        for (DDLogFileInfo *logFileInfo in self.logFiles) {            //除了當前 其它進行清除            if (logFileInfo.isArchived) {                [[NSFileManager defaultManager] removeItemAtPath:logFileInfo.filePath error:nil];            }        }        [self loadLogFiles];        [self.myTableView reloadData];    }}@end

這邊把表格分成兩部分,一部分是記錄檔的列表,以及一個清除功能,清除功能主要是對先前的檔案進行刪除的操作,讀取日誌的個數及日誌時間,日誌詳細內容

DDLogFileInfo

6:異常的詳細資料頁面

LoggerDetailViewController.h代碼#import <UIKit/UIKit.h>@interface LoggerDetailViewController : UIViewController- (id)initWithLog:(NSString *)logText forDateString:(NSString *)logDate;@end
LoggerDetailViewController.m檔案#import "LoggerDetailViewController.h"@interface LoggerDetailViewController ()@property (nonatomic, strong) NSString *logText;@property (nonatomic, strong) NSString *logDate;@property (nonatomic, strong) UITextView *textView;@end@implementation LoggerDetailViewController- (void)viewDidLoad {    [super viewDidLoad];        self.textView = [[UITextView alloc] initWithFrame:self.view.bounds];    self.textView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;    self.textView.editable = NO;    self.textView.text = self.logText;    [self.view addSubview:self.textView];}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}- (id)initWithLog:(NSString *)logText forDateString:(NSString *)logDate{    self = [super initWithNibName:nil bundle:nil];    if (self) {        _logText = logText;        _logDate = logDate;        self.title = logDate;    }    return self;}@end

 這樣便可以實現不管在哪個頁面出出異常都可以進行記錄,因為執行個體比較小,如果要原始碼可以留下郵箱統一進行發送;

IOS異常日誌記錄與展現功能

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.