第一种方法 使用ExceptionHandler
用网上的一段代码
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[window makeKeyAndVisible];
[NdUncaughtExceptionHandler setDefaultHandler];
NSArray *array = [NSArray arrayWithObject:@"there is only one objective in this arary,call index one, app will crash and throw an exception!"];
NSLog(@"%@", [array objectAtIndex:1]);
return YES;
}
基本接口展示:
#import <Foundation/Foundation.h>
@interface NdUncaughtExceptionHandler : NSObject {
}
+ (void)setDefaultHandler;
+ (NSUncaughtExceptionHandler*)getHandler;
@end
//还可以选择设置自定义的handler,让用户取选择
接口实现展示
#import "NdUncaughtExceptionHandler.h"
NSString *applicationDocumentsDirectory() {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
void UncaughtExceptionHandler(NSException *exception) {
NSArray *arr = [exception callStackSymbols];
NSString *reason = [exception reason];
NSString *name = [exception name];
NSString *url = [NSString stringWithFormat:@"=============异常崩溃报告=============\nname:\n%@\nreason:\n%@\ncallStackSymbols:\n%@",
name,reason,[arr componentsJoinedByString:@"\n"]];
NSString *path = [applicationDocumentsDirectory() stringByAppendingPathComponent:@"Exception.txt"];
[url writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];
//除了可以选择写到应用下的某个文件,通过后续处理将信息发送到服务器等
//还可以选择调用发送邮件的的程序,发送信息到指定的邮件地址
//或者调用某个处理程序来处理这个信息
}
@implementation NdUncaughtExceptionHandler
-(NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
+ (void)setDefaultHandler
{
NSSetUncaughtExceptionHandler (&UncaughtExceptionHandler);
}
+ (NSUncaughtExceptionHandler*)getHandler
{
return NSGetUncaughtExceptionHandler();
}
@end
第二种方法
使用PLCrashReporter框架
借鉴google的
PLCrashReporter provide an in-process CrashReporter framework for the iPhone and Mac OS X. This framework is very helpful in getting the crash report for your app from beta tester or real users.
<img src="http://caydenliew.com/wp-content/uploads/2011/11/PLCrashReporter-190x300.jpg" real_src="http://caydenliew.com/wp-content/uploads/2011/11/PLCrashReporter-190x300.jpg" alt="PLCrashReporter" name="image_operate_66171337333021626" title="iOS Exception caught Crash Report" style="margin:0px;padding:0px;list-style:none;" />
I’m not sure how most of the developer ask for the crash report from their users, but one way is to ask them to connect their IOS device to iTune, get the crash report and send them manually, but this is just too troublesome.
With PLCrashReporter, you can capture the logs and output a crash report and your users can choose to send the report to the developer directly within the app.
To start using PLCrashReporter,
First download the
source release. Extract the package and run the Xcode project, we need to build the crashreport framework using the source before we can use it in our project.
There are a lot of Targets, for this example lets use only the simulator Target. Navigate to the CrashReporter-iPhoneSimulator Target. Under the Build Settings, set “Perform Single-Object Prelink” to “No”, “Mach-O Type” to “Static Library”.
Select your simulator as iphone simulator and then click build.
A static library should be built now, navigate to your build directory for the PLCrashReporter, eg. /Users/username/Library/Developer/Xcode/DerivedData/CrashReporter-(random characters)/Build/Products/Debug-iphonesimulator and copy the libCrashReporter-iphonesimulator.a to your project that use the PLCrashReporter.
Now, download the
PLCrashReporter binary release and extract the framework to a local directory.
Open your new project, and add the CrashReporter framework to your project. To add a new framework, click on your project name in XCode, click on your target, under ‘Build Phases’ -> ‘Link Binary with libraries’, click the ‘+’, and ‘add other’. Look for the ‘libCrashReporter-iphonesimulator.a’ you’ve built and the CrashReporter.framework you’ve downloaded, add them into the project.
Now you are ready to use the CrashReporter framework. There’s a demo project in the source release you’ve downloaded, you can run the project and see how it works.
For XCode 4, the CrashReporter might have problem in creating the report. If it doesn’t work, you can try to switch off the GDB debugger. To do this, in XCode, go to Product -> Edit Scheme -> Select the debugger as ‘None’.
If it works, you should be able to see a report ‘live_report.plcrash’ under your ‘application directory/library/caches/com.plausiblelabs.crashreporter.data/com.yourcompany.CrashReporterDemo/’ after you trigger a crash in the demo project.
With PLCrashReporter, you can provide a simpler way for your Beta tester or real users to send the crash report back to you.
因為app常常crash 所以去google做了一下功課,找到了這篇:
Send Crash Reports from within App,發現foursquare也是用 plcrashreporter 這個framework,所以就來研究一下。
1.首先到 http://code.google.com/p/plcrashreporter/ 下載最新framework版本plcrashreporter1.0.1,然後import到自己的project裡面。
2.參考 Example iPhone Usage 的範例,本身是用xcode 4.1去compile & run,確定可以使用,但是如果發現
會造成crash的話,請確定一下是否是下載最新的plcrashreporter。
3.當app在執行期間發生了crash,下次再開啓app的時候,我們可以利用以下程式碼 ,將上次crash的crashreport寄給自己。
1.首先到 http://code.google.com/p/plcrashreporter/ 下載最新framework版本plcrashreporter1.0.1,然後import到自己的project裡面。
2.參考 Example iPhone Usage 的範例,本身是用xcode 4.1去compile & run,確定可以使用,但是如果發現
PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter];
會造成crash的話,請確定一下是否是下載最新的plcrashreporter。
3.當app在執行期間發生了crash,下次再開啓app的時候,我們可以利用以下程式碼 ,將上次crash的crashreport寄給自己。
PLCrashReporter *crashReporter =[PLCrashReporter sharedReporter];
NSData *crashData;
NSError *error;
crashData = [crashReporterloadPendingCrashReportDataAndReturnError:&error];
MFMailComposeViewController *picker =[[MFMailComposeViewController alloc] init];
[picker addAttachmentData:crashDatamimeType:@"application/octet-stream"fileName:@"crashfile.crash"];
[self presentModalViewController:pickeranimated:YES];
[picker release];
4.拿到crashreport之後,打開plcrashreport 1.0.1裡面的tool folder,利用裡面的
plcrashutil解碼(termail裡面打入
./plcrashutilconvert --format=iphoneexample_report.
plcrash ),可以得到完整的crashreport。
5.配合dsym file 做symbolicate即可以看到app crash在那個檔案的那一行。可參考
http://blog.sina.com.cn/s/blog_67b7cb7b01014h2x.html
6.如果發現沒辦法看到crash出現在那一行的話,我的解決辦法是將利用plcrashutil解碼後的crashreport 裡面version 103改成 104,然後將所有的 ???(???) 取代成armv7,再做synbpilcate即可。
还有第三种
采用 CrashKit 这个类库
三种方法比较起来还是这个简单点,呵呵 ..
去googlecode下载最新版本
1.拷贝 CrashController , CrashLogger 四个文件到项目中
2.在AppDelegate中实现 CrashSaveDelegate 委托
3.下面就可以在AppDelegate.m文件中实现代码
CrashController *crash = [CrashController sharedInstance];
crash.delegate = self;
// 类库提供两种方式 ,邮件和服务器
//邮件
[crash sendCrashReportsToEmail:@"crash@smartfulstudios.com"
withViewController:appDelegate.navigationController];
//服务器
[crash sendCrashReportsToBugzScoutURL:@"https://smartfulstudios.fogbugz.com/api.asp"
withUser:@".com"
password:@""
forProject:@"Inbox"
withArea:@"Misc"];
完成这些,别忘记实现onCrash回调方法
- (void)onCrash
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Crash"
message:@"The App has crashed and will attempt to send a crash report"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
OK了.很简单!
不过 crashkit 目前只支持 ipad3.0