iOS 開發App捕獲異常, 反饋給伺服器, 提高使用者體驗,iosapp
在我們開發的app中, 不可避免的, 有時候使用者使用軟體會崩潰. 我們就需要捕獲異常, 可以在入口類中加入相應的代碼, 可以在每次使用者開啟程式的時候, 檢查一下沙箱中是否有崩潰日誌, 如果有, 可以發送給伺服器, 方便改進軟體.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
ExceptionHandler 捕獲異常的宏定義
// 這裡反饋給伺服器
self.window.rootViewController = [ViewController new];
return YES;
}
宏定義
#define ExceptionHandler [ZYExceptionHandler caughtExceptionHandler];
#import "ZYExceptionHandler.h"
#include <libkern/OSAtomic.h>
#include <execinfo.h>
@implementation ZYExceptionHandler
+ (void)caughtExceptionHandler{
//指定crash的處理方法。
NSSetUncaughtExceptionHandler(& UncaughtExceptionHandler);
}
+ (void)fileCreate{
NSString *path = [ZYExceptionHandler exceptionPath];
NSFileManager *manager =[NSFileManager defaultManager];
//檔案不存在時建立
if (![manager fileExistsAtPath:path])
{
NSString *dateString = [ZYExceptionHandler currentTime];
NSString *logStr = [NSString stringWithFormat:@"================\n檔案建立時間:%@\n================",dateString];
NSData *data = [logStr dataUsingEncoding:NSUTF8StringEncoding];
[data writeToFile:path atomically:YES];
}
}
void UncaughtExceptionHandler(NSException *exception) {
/**
* 擷取異常崩潰資訊
*/
//在這裡建立一個接受crash的檔案
[ZYExceptionHandler fileCreate];
NSArray *callStack = [exception callStackSymbols];
NSString *reason = [exception reason];
NSString *name = [exception name];
NSString *dateString = [ZYExceptionHandler currentTime];
NSString *systemName = [[UIDevice currentDevice] systemName];
NSString *strModel = [[UIDevice currentDevice] model];
NSDictionary* infoDict =[[NSBundle mainBundle] infoDictionary];
NSString *bundleIdentifier = infoDict[@"CFBundleIdentifier"];
NSString* versionNum = [infoDict objectForKey:@"CFBundleShortVersionString"];
NSString *content = [NSString stringWithFormat:@"\n\n\n========異常錯誤報表========\n錯誤時間:%@ 系統:%@ 裝置:%@\n目前的版本:%@ 當前唯一標示符:%@\n\n錯誤名稱:%@\n錯誤原因:\n%@\ncallStackSymbols:\n%@\n\n========異常錯誤結束========\n",dateString,systemName,strModel,versionNum,bundleIdentifier,name,reason,[callStack componentsJoinedByString:@"\n"]];
NSString *path = [ZYExceptionHandler exceptionPath];
NSFileHandle *outFile = [NSFileHandle fileHandleForWritingAtPath:path];
//找到並定位到outFile的末尾位置(在此後追加檔案)
[outFile seekToEndOfFile];
[outFile writeData:[content dataUsingEncoding:NSUTF8StringEncoding]];
//關閉讀寫檔案
[outFile closeFile];
}
+ (NSString *)exceptionPath{
NSLog(@"----->>>%@",NSHomeDirectory());
NSString *documents = [NSHomeDirectory()stringByAppendingPathComponent:@"Documents"];
NSString *path = [documents stringByAppendingPathComponent:@"exceptionHandler.txt"];
return path;
}
+ (NSString *)currentTime{
NSDate *date = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd hh:mm"];
NSString *dateString = [formatter stringFromDate:date];
return dateString;
}
//擷取呼叫堆疊
+ (NSArray *)backtrace
{
void* callstack[128];
int frames = backtrace(callstack, 128);
char **strs = backtrace_symbols(callstack,frames);
NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
for (int i=0;i<frames;i++)
{
[backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
}
free(strs);
return backtrace;
}
@end