[IOS] 相仿 LeanCloud 的 Crash 收集实现

[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

同时 也看到一个对 基本数据类型、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

[IOS] 相仿 LeanCloud 的 Crash 收集实现


 自己可不可以实现呢? 从邮件的信息看,基本和 AVOS Log  一致 可以实现简单的Crash 收集

代码如下:

- (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 收集功能,收集设备型号、系统自行加代码:

[IOS] 相仿 LeanCloud 的 Crash 收集实现