iOS Crash閃退日誌獲取和上傳至伺服器
如何獲取crash閃退日誌 -- 工具檢視
先看第一個問題如何檢視,我搜索的方法有以下幾個:
第一個方法:XCode 的選單Window->Organizer 選擇Devices -> 選中的手機 -> 點選手機名稱左邊的箭頭 會等到如下圖
注意對比一下紅色框框內容,這個日誌也基本上上告訴你crash的原因了。
第二種方法 開啟手機 - > 設定 -> 隱私 - > 診斷與用量 - > 診斷與用量資料 這裡面就是所有應用的Crash日誌。
第三種方法 通過iTunes Connect(Manage Your Applications - View Details - Crash Reports)獲取使用者的crash日誌。方法很多這裡不多列了。
解析crash
參見:http://stackoverflow.com/questions/1460892/symbolicating-iphone-app-crash-reports )
用程式獲取crash日誌
但是這裡都是工具,沒有用到程式獲取,經過千方百計的查詢(思路是:先找到存放crash的iphone系統路徑:var/mobile/Library/Logs/CrashReporter)找到了crash存放的路徑,唉,苦於無法讀取(用程式讀出來都是nil),當然如果是越獄手機就不一樣是可以讀取的。這個思路斷掉了。
換個思路:自己用程式捕獲crash,儲存到本地可以嗎?這麼一試,果然........
第一步:新建一個繼承自NSObject的類(Xcode新建一個空專案過程略),取名字CatchCrash,在h和m檔案中寫下:
.h檔案
-
#import <Foundation/Foundation.h>
-
@interface CatchCrash : NSObject
-
void uncaughtExceptionHandler(NSException *exception);
-
@end
.m檔案
-
#import "CatchCrash.h"
-
@implementation CatchCrash
-
void uncaughtExceptionHandler(NSException *exception)
-
{
-
// 異常的堆疊資訊
-
NSArray *stackArray = [exception callStackSymbols];
-
// 出現異常的原因
-
NSString *reason = [exception reason];
-
// 異常名稱
-
NSString *name = [exception name];
-
NSString *exceptionInfo = [NSString stringWithFormat:@"Exception reason:%@\nException name:%@\nException stack:%@",name, reason, stackArray];
-
NSLog(@"%@", exceptionInfo);
-
NSMutableArray *tmpArr = [NSMutableArray arrayWithArray:stackArray];
-
[tmpArr insertObject:reason atIndex:0];
-
//儲存到本地 -- 當然你可以在下次啟動的時候,上傳這個log
-
[exceptionInfo writeToFile:[NSString stringWithFormat:@"%@/Documents/error.log",NSHomeDirectory()] atomically:YES encoding:NSUTF8StringEncoding error:nil];
-
}
-
@end
第二步:新增一個繼承自UIViewcontroller的類,取名字為TestViewController。
第三步:註冊CatchCrash異常處理方法,在Appdelegate寫下如下程式碼:
-
#import "AppDelegate.h"
-
#import "CatchCrash.h"
-
#import "TestViewController.h"
-
@implementation AppDelegate
-
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
-
{
-
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
-
// Override point for customization after application launch.
-
//註冊訊息處理函式的處理方法
-
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
-
TestViewController *testVc = [[TestViewController alloc] init];
-
self.window.rootViewController = testVc;
-
self.window.backgroundColor = [UIColor whiteColor];
-
[self.window makeKeyAndVisible];
-
return YES;
-
}
第四部:在TestViewController的Xib上面新增一個按鈕並給其新增一個單擊事件,TestViewController.m檔案中有如下程式碼:
-
#import "TestViewController.h"
-
@interface TestViewController ()
-
@end
-
@implementation TestViewController
-
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
-
{
-
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
-
if (self) {
-
// Custom initialization
-
}
-
return self;
-
}
-
- (void)viewDidLoad
-
{
-
[super viewDidLoad];
-
// Do any additional setup after loading the view from its nib.
-
}
-
- (void)didReceiveMemoryWarning
-
{
-
[super didReceiveMemoryWarning];
-
// Dispose of any resources that can be recreated.
-
}
-
#pragma mark - 單擊事件
-
- (IBAction)crashTapped:(id)sender
-
{
-
//常見異常1---不存在方法引用
-
// [self performSelector:@selector(thisMthodDoesNotExist) withObject:nil];
-
//常見異常2---鍵值對引用nil
-
// [[NSMutableDictionary dictionary] setObject:nil forKey:@"nil"];
-
//常見異常3---陣列越界
-
[[NSArray array] objectAtIndex:1];
-
//常見異常4---memory warning 級別3以上
-
// [self performSelector:@selector(killMemory) withObject:nil];
-
//其他大家去想吧
-
}
-
#pragma mark - custom method
-
- (void) killMemory
-
{
-
for (int i = 0; i <300; i ++)
-
{
-
UILabel *tmpLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];
-
tmpLabel.layer.masksToBounds = YES;
-
tmpLabel.layer.cornerRadius = 10;
-
tmpLabel.backgroundColor = [UIColor redColor];
-
[self.view addSubview:tmpLabel];
-
}
-
}
-
@end
執行程式碼:可以看到閃退,匯出error日誌,我們可以看到:
-
Exception reason:NSRangeException
-
<spanstyle="color:#FF0000;">Exception name:*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds for empty array</span>
-
Exception stack:(
-
0 CoreFoundation 0x2f2edfeb <redacted> + 154
-
1 libobjc.A.dylib 0x39b66ccf objc_exception_throw + 38
-
2 CoreFoundation 0x2f224a89 <redacted> + 176
-
<spanstyle="color:#FF0000;"> 3 TestCrash 0x000e8077 -[TestViewController crashTapped:] + 126</span>
-
4 UIKit 0x31b3f057 <redacted> + 90
-
5 UIKit 0x31b3eff7 <redacted> + 30
-
6 UIKit 0x31b3efd1 <redacted> + 44
-
7 UIKit 0x31b2a737 <redacted> + 374
-
8 UIKit 0x31b3ea4f <redacted> + 590
-
9 UIKit 0x31b3e721 <redacted> + 528
-
10 UIKit 0x31b396eb <redacted> + 758
-
11 UIKit 0x31b0e8ed <redacted> + 196
-
12 UIKit 0x31b0cf97 <redacted> + 7102
-
13 CoreFoundation 0x2f2b925b <redacted> + 14
-
14 CoreFoundation 0x2f2b872b <redacted> + 206
-
15 CoreFoundation 0x2f2b6f1f <redacted> + 622
-
16 CoreFoundation 0x2f221f0f CFRunLoopRunSpecific + 522
-
17 CoreFoundation 0x2f221cf3 CFRunLoopRunInMode + 106
-
18 GraphicsServices 0x3417a663 GSEventRunModal + 138
-
19 UIKit 0x31b6d16d UIApplicationMain + 1136
-
20 TestCrash 0x000e810d main + 116
-
21 libdyld.dylib 0x3a073ab7 <redacted> + 2
-
)