iOS-crashログのキャプチャ保存
7945 ワード
幸いAppleはすでに私たちに方法を提供してくれました.そうしないと、カニを食べている人にどれだけの脳細胞を死なせなければなりませんか.
個人的な拙見.
これはシステム定義の1つの方法で、私たちに1つの方法のアドレス(むやみに書くことができない)を伝えて、プログラムが潰れたらこの方法をトリガーして、log情報を取得するだけではなくて、データを保存することができます.
typedef void NSUncaughtExceptionHandler(NSException *exception);
FOUNDATION_EXPORT NSUncaughtExceptionHandler * _Nullable NSGetUncaughtExceptionHandler(void);
FOUNDATION_EXPORT void NSSetUncaughtExceptionHandler(NSUncaughtExceptionHandler * _Nullable);
AppDelegateにそんなに冗長なコードを書かないように、少しパッケージしました
1、先頭ファイルを先にインポートする
#import "PQCatchErrorLog.h"
2、「登録」でログを取る
,
, , , 。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[PQCatchErrorLog catchLog];
[PQCatchErrorLog printErrorLog];
return YES;
}
3、...
それから?そしてなくなりました...また提供しました
/**
LOG
@return log - NSString
*/
+ (NSString *)logInfo;
/**
LOG ,
@return log - Data
*/
+ (NSData *)logData;
/**
error
@return
*/
+ (BOOL)delErrorLogFile;
対応する実装コード
+ (void)catchLog{
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
}
- (instancetype)init
{
self = [super init];
if (self) {
//
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
}
return self;
}
+ (void)printErrorLog{
NSLog(@"path - %@
errorLog - %@",LOGFilePath,[PQCatchErrorLog logInfo]);
}
+ (NSString *)logInfo{
return [NSString stringWithContentsOfFile:LOGFilePath encoding:NSUTF8StringEncoding error:nil];
}
+ (NSData *)logData{
return [[PQCatchErrorLog logInfo] dataUsingEncoding:NSUTF8StringEncoding];
}
+ (BOOL)delErrorLogFile{
NSError * error;
[[NSFileManager defaultManager] removeItemAtPath:LOGFilePath error:&error];
if (!error) {
return YES;
}
NSLog(@"
- %@",error);
return NO;
}
そして時間を記録するために、クラスに一緒に書くカテゴリメソッドも書きました.
.h
// ---------------- -----------------
@interface NSDate (PQCatchErrorLog)
/**
@return
*/
+ (NSString *)currentDateForDateSeconds;
@end
.m
/**
@return
*/
+ (NSString *)currentDateForDateSeconds{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *destDateString1 = [dateFormatter stringFromDate:[NSDate date]];
NSString *destDateString = [destDateString1 substringFromIndex:2];
return destDateString;
}
もう一つのアドレスがつながっています
.h
// ---------------- -----------------
@interface NSString (PQCatchErrorLog)
/**
@return
*/
- (NSString *)byAppendToCacheDocument;
@end
.m
/**
@return
*/
- (NSString *)byAppendToCacheDocument{
NSString * path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
return [path stringByAppendingPathComponent:self];
}
最後に、ロゴ情報を保存する方法について説明します.
//
void UncaughtExceptionHandler(NSException *exception) {
NSArray *arr = [exception callStackSymbols];//
NSString *reason = [exception reason];// ,
NSString *name = [exception name];//
NSMutableString * log = [NSMutableString stringWithFormat:@"callStackSymbols - :
"];
for (NSString * str in arr) {
[log appendFormat:@"%@
",str];
}
[log appendFormat:@"
reason - :
%@",reason];
[log appendFormat:@"
name - :
%@",name];
[log insertString:[NSString stringWithFormat:@"*************** %@ *******************
",[NSDate currentDateForDateSeconds]] atIndex:0];
// ,
if (![[NSFileManager defaultManager]fileExistsAtPath:LOGFilePath]) {
[[NSFileManager defaultManager]createFileAtPath:LOGFilePath contents:nil attributes:nil];
[log insertString:[NSString stringWithFormat:@"
*************** *******************
"] atIndex:0];
[log writeToFile:LOGFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
return;
}
// fileHandler
NSFileHandle * fileHandler = [NSFileHandle fileHandleForWritingAtPath:LOGFilePath];
//
[fileHandler seekToEndOfFile];
//
[fileHandler writeData:[log dataUsingEncoding:NSUTF8StringEncoding]];
// file Handler
[fileHandler closeFile];
}
最后にわざとViewControllerの中で1つの配列の境界を越えるBUGを书いてみんなは自分で感じます:
*************** *******************
*************** 16-11-28 15:32:47 *******************
callStackSymbols - :
0 CoreFoundation 0x000000010c91634b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010c37721e objc_exception_throw + 48
2 CoreFoundation 0x000000010c96ebdf -[__NSSingleObjectArrayI objectAtIndex:] + 111
3 CatchErrorLog 0x000000010bda22a3 -[ViewController viewDidLoad] + 163
4 UIKit 0x000000010cedac99 -[UIViewController loadViewIfRequired] + 1258
5 UIKit 0x000000010cedb0cc -[UIViewController view] + 27
6 UIKit 0x000000010cda4c51 -[UIWindow addRootViewControllerViewIfPossible] + 71
7 UIKit 0x000000010cda53a2 -[UIWindow _setHidden:forced:] + 293
8 UIKit 0x000000010cdb8cb5 -[UIWindow makeKeyAndVisible] + 42
9 UIKit 0x000000010cd31c89 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4818
10 UIKit 0x000000010cd37de9 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1731
11 UIKit 0x000000010cd34f69 -[UIApplication workspaceDidEndTransaction:] + 188
12 FrontBoardServices 0x000000010fe87723 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
13 FrontBoardServices 0x000000010fe8759c -[FBSSerialQueue _performNext] + 189
14 FrontBoardServices 0x000000010fe87925 -[FBSSerialQueue _performNextFromRunLoopSource] + 45
15 CoreFoundation 0x000000010c8bb311 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
16 CoreFoundation 0x000000010c8a059c __CFRunLoopDoSources0 + 556
17 CoreFoundation 0x000000010c89fa86 __CFRunLoopRun + 918
18 CoreFoundation 0x000000010c89f494 CFRunLoopRunSpecific + 420
19 UIKit 0x000000010cd337e6 -[UIApplication _run] + 434
20 UIKit 0x000000010cd39964 UIApplicationMain + 159
21 CatchErrorLog 0x000000010bda280f main + 111
22 libdyld.dylib 0x000000010f6f668d start + 1
reason - :
*** -[__NSSingleObjectArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 0]
name - :
NSRangeException
3行目:どの方法で
2行目:表示されたのは配列で値を取ります
クラッシュ原因で落札されました:配列境界
最後の行は、例外タイプです.
最後の最後のDEMOアドレスが役に立つ場合はstarをお願いします