开发者

Objective-C/iPhone - NSException capturing as much information as possible

开发者 https://www.devze.com 2023-02-20 20:20 出处:网络
I\'m using the following code to capture exceptions in my app: void uncaughtExceptionHandler(NSException *exception) {

I'm using the following code to capture exceptions in my app:

void uncaughtExceptionHandler(NSException *exception) {
    [FlurryAPI logError:@"Uncaught" message:@"Crash!" exception:exception];
}

Just wondering whether开发者_StackOverflow I can pin-point, line numbers, UIView, classes, etc that the error's occurring on. Ideally I'd like as much detailed information as I can get, since it's captured by FlurryAPI analytics.

FlurryAPI: http://www.flurry.com/


I ended up going with this:

void uncaughtExceptionHandler(NSException *exception) {
    NSArray *backtrace = [exception callStackSymbols];
    NSString *platform = [[UIDevice currentDevice] platform];
    NSString *version = [[UIDevice currentDevice] systemVersion];
    NSString *message = [NSString stringWithFormat:@"Device: %@. OS: %@. Backtrace:\n%@",
                         platform,
                         version,
                         backtrace];

    [FlurryAPI logError:@"Uncaught" message:message exception:exception];
}

UPDATE (based on @TommyG's comment below):

Add NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler); to the end of your - -(BOOL)application:didFinishLaunchingWithOptions: method in AppDelegate. Then add the above method to the AppDelegate as well.


You can make advantage of the precompiler and write a macro which gathers all the values, eg:

#define __ThrowException(name, reason, class, function, file, line, info) [NSException exceptionWithName:name reason:[NSString stringWithFormat:@"%s:%i (%@:%s) %@", file, line, class, function, reason]  userInfo:info];
#define ThrowException(name, reason, info) __ThrowException(name, reason, [self class], _cmd, __FILE__, __LINE__, info)

However, this only works when you throw an exception and from inside an ObjC function (self and _cmd are the very first parameters you get in an ObjC function, where self is an id which points to the class and _cmd to the selector which can be (currently!) typecasted to const char).

However, if you want this only for Foundation exceptions, you have two options:

  1. Wrap everything that might throw an exception in @try() @catch() blocks and then throw a new, custom, exception
  2. Get the stack trace, this is what might be a little more hard as your app is possible in an inconsistent state and can't gather all the values. Gathering the current stack trace is covered here in great detail.
0

精彩评论

暂无评论...
验证码 换一张
取 消