In the common application development process often encountered the problem of abnormal flash, through the log can be related to the detailed error information record, this instance to record regardless of which page error is to be recorded, this side used to the log record plug-in Cocoalumberjack, Record the error message as text, and then read the contents of each text to display; Of course, there are a lot of third-party plug-ins, such as Friends of the League has also integrated the function of error logging;
As follows:
1: Class for encapsulating Ddlogger
MyFileLogger.h file #import <Foundation/Foundation.h>#import <CocoaLumberjack.h>@interface Myfilelogger:nsobject@property (Nonatomic, Strong, ReadWrite) Ddfilelogger *filelogger;+ (Myfilelogger *) Sharedmanager; @end
MYFILELOGGER.M file #import "MyFileLogger.h"@implementation Myfilelogger#pragma mark-inititlization-(instancetype) init{self =[Super Init]; If (self) {[self configurelogging]; } return self;} #pragma mark Singleton mode static Myfilelogger *sharedmanager= nil;+ (Myfilelogger * ) sharedmanager{static dispatch_once_t once; Dispatch_once (&once, ^ {sharedmanager= [[Self alloc]init];}); return Sharedmanager;} #pragma mark-Log type-(void ) configurelogging{#ifdef DEBUG [Ddlog Addlogger:[ddasllogger sharedinstance]]; [Ddlog Addlogger:[ddttylogger sharedinstance]; #endif [Ddlog AddLogger:self.fileLogger];} #pragma mark-Initialize the file record type-(Ddfilelogger * ) filelogger{if (! _filelogger) {Ddfilelogger *filelogger = [[Ddfilelogger alloc] init]; filelogger.rollingfrequency = 60 * 60 * 24; /hour Rolling fileLogger.logFileManager.maximumNumberOfLogFiles = 7 ; _filelogger = filelogger;} return _filelogger;} @end
This way is set 24 hours to record a file
2: Out of the exception to record
MyExceptionHandler.h file #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:@ "======== exception error Report ========\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:@ "======== exception error Report ========\nname:%@\nreason:\n%@\ncallstacksymbols:\n%@", Name,reason,[arr componentsjoinedbystring:@ "\ n"]; Ddlogerror (@ "%@", URL);} @end
This file is also executed when an exception occurs
3:contents of appdelegate configuration
AppDelegate.h file contents #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 file: #import "AppDelegate.h" @interface appdelegate () @end @implementation appdelegatestatic const int ddloglevel = log_level_verbose;-(BOOL) Application: (UIApplication *) application Didfinishlaunchingwithoptions: (nsdictionary * ) launchoptions {//Initialize [Myexceptionhandler Setdefaulthandl ER]; Self.logger= [[Myfilelogger alloc]init]; NSString *path = Nshomedirectory ();//main directory NSLog (@ "Path of current project:%@" , path); return YES;} -(void) Applicationwillresignactive: (uiapplication * ) application {}-(void) Applicationdidenterbackground: ( UIApplication * ) application {}-(void) Applicationwillenterforeground: (uiapplication * ) application {}-( void) Applicationdidbecomeactive: (uiapplication * ) application {}-(void) Applicationwillterminate: ( UIApplication * ) application {} @end
The focus here is to set the record level of the Ddlog Ddloglevel, as well as the initialization of the above two files [myexceptionhandler setdefaulthandler]; Self. Logger=[[myfilelogger alloc]init];
Implementation of the above code has been able to record the contents of the exception;
4: Create an incorrect exception code
-(void) viewdidload { [super viewdidload]; Nsarray *[email protected][@ "123", @ "444"]; ID testid=test[5];}
Execution to this code will record the contents of the exception, followed by the content of the display, is a list of each log file, and then a detailed page to display;
5: Log List
LoggerTableViewController.h file #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];//load log file Appdelegate *delegate = (appdelegate *) [[UIApplication sharedapplication] de Legate]; _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]; }}//number of files read log-(void) loadlogfiles{Self.logfiles =Self.fileLogger.logFileManager.sortedLogFileInfos;} Time Format-(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) {returnSelf.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 (Ten, [[UIScreen Mainscreen] Bounds].size.width, 30)]; [email protected] "journal list"; [Headview Addsubview:mylabel]; } returnHeadview;} -(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 (@ "current", @ "" "): [Self.dateformatter stringFromDate:logFileInfo.creationDate]; Cell.textLabel.textAlignment =Nstextalignmentleft; } else{Cell.accessorytype =Uitableviewcellaccessorynone; Cell.textLabel.textAlignment =Nstextalignmentcenter; Cell.textLabel.text = nslocalizedstring (@ "Clean up old records" @ "" "); } returnCell;} #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) {///except for the current other purge if (logfileinfo.isarchived) { [[Nsfilemanager Defaultmanager] RemoveItemAtPath:logFileInfo.filePath Error:nil]; }} [self loadlogfiles]; [Self.mytableview Reloaddata]; }} @end
This way, the table is divided into two parts, a list of log files, and a clear function, clear function is mainly to delete the previous files, read the number of logs and log time, log details
Ddlogfileinfo
6: Exception Details page
LoggerDetailViewController.h code #import <UIKit/UIKit.h>@interface Loggerdetailviewcontroller: uiviewcontroller-(ID) Initwithlog: (NSString *) LogText fordatestring: (NSString *) logdate; @end
LOGGERDETAILVIEWCONTROLLER.M file #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 so 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
This can be implemented regardless of which page out of the exception can be recorded, because the instance is relatively small, if the source code can leave the mailbox unified send;
iOS exception logging and presentation features