[IOS] 類似 LeanCloud 的 Crash 收集實現
用慣了 crashlytics ,Crash 收集功能的確很強大,各種 Crash 收集,而且即時給開發人員發送郵件
詳情見:唐巧一篇文章
國內的 Crash 的第三方,相比之下就 Low 很多,畢竟人家也是專業做 Crash 的,貌似被 Twitter收購了
但是你想過沒有自己實現一個簡單的 Crash 收集呢,比國內的第三方簡陋些,可以實現準系統呢?
先說 Crash ,App 最致命的問題,使用者第一反應可以刪,然後再說說對 Crash 怎麼辦?
NSDictionary Crash ,Range 超過範圍了Crash ,各種 Crash
首先想到的是, Try Catch ,實現如下:
@try { // 1 NSString *str = @"hello world"; [str substringFromIndex:200]; // 程式到這裡會崩 } @catch (NSException *exception) { // 2 NSLog(@"%s\n%@", __FUNCTION__, exception); // @throw exception; // 這裡不能再拋異常 } @finally { // 3 NSLog(@"最終,我還是執行啦"); } // 4 // 這裡一定會執行 NSLog(@"Yeah,pass");
這時想到了Apple 官方用 Try Catch 實現的斷言 XC
/*! * @define XCTAssertNil(expression, ...) * Generates a failure when ((\a expression) != nil). * @param expression An expression of id type. * @param ... An optional supplementary description of the failure. A literal NSString, optionally with string format specifiers. This parameter can be completely omitted.*/#define XCTAssertNil(expression, ...) \ _XCTPrimitiveAssertNil(self, expression, @#expression, __VA_ARGS__)#define _XCTPrimitiveAssertNil(test, expression, expressionStr, ...) \({ \ @try { \ id expressionValue = (expression); \ if (expressionValue != nil) { \ _XCTRegisterFailure(test, _XCTFailureDescription(_XCTAssertion_Nil, 0, expressionStr, expressionValue), __VA_ARGS__); \ } \ } \ @catch (_XCTestCaseInterruptionException *interruption) { [interruption raise]; } \ @catch (NSException *exception) { \ _XCTRegisterFailure(test, _XCTFailureDescription(_XCTAssertion_Nil, 1, expressionStr, [exception reason]), __VA_ARGS__); \ } \ @catch (...) { \ _XCTRegisterFailure(test, _XCTFailureDescription(_XCTAssertion_Nil, 2, expressionStr), __VA_ARGS__); \ } \})
有點意思,調試時方便很多,對資料模型處理時方便很多,但是總有想不到的Crash
同時 也看到一個對 基礎資料型別 (Elementary Data Type)、KVO 的 Crash 處理的 第三方還不錯推薦下 DurexKit
http://code4app.com/ios/DurexKit%E5%AE%89%E5%85%A8%E5%B7%A5%E5%85%B7%E5%8C%85/5325b421933bf0463d8b49ec
回到正題,國內Crash收集是什麼樣子,比如 Crash 的 log ,給個 AVOS 的 Crash log
<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+INfUvLq/ybK7v8nS1Mq1z9bE2KO/ILTT08q8/rXE0MXPor+0o6y7+bG+us0gQVZPUyBMb2cgINK71sIgv8nS1Mq1z9a88rWltcRDcmFzaCDK1byvPC9wPgo8cD60+sLryOfPwqO6PC9wPgo8cD48L3A+CjxwcmUgY2xhc3M9"brush:java;">- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. // 最好放在其他代碼之前 NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler); NSString *str = @"abc"; [str substringFromIndex:111]; // 程式到這裡會崩 return YES;}
void UncaughtExceptionHandler(NSException *exception) { /** * 擷取異常崩潰資訊 */ NSArray *callStack = [exception callStackSymbols]; NSString *reason = [exception reason]; NSString *name = [exception name]; NSString *content = [NSString stringWithFormat:@"========異常錯誤報表========\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",name,reason,[callStack componentsJoinedByString:@"\n"]]; /** * 把異常崩潰資訊發送至開發人員郵件 */ NSMutableString *mailUrl = [NSMutableString string]; [mailUrl appendString:@"mailto:tskyming@163.com"]; [mailUrl appendString:@"?subject=程式異常崩潰,請配合發送異常報告,謝謝合作!"]; [mailUrl appendFormat:@"&body=%@", content]; // 開啟地址 NSString *mailPath = [mailUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; [[UIApplication sharedApplication] openURL:[NSURL URLWithString:mailPath]];}
郵件內容如下,基本實現了AVOS的Crash 收集功能,收集裝置型號、系統自行加代碼: