Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to execute code after an uncaught exception in iOS? [duplicate]

I have been working on a framework for several applications which implements multi-level logging. It is mainly used in applications used in-house to test communications with other devices, yet is also used in some applications that we will be distributing.

Is there any way to catch an uncaught exception and promptly execute code to save the exception to the log file? At the moment, the Log class simply writes to file every so often, alternating between two files in case of write failure, etc. This works alright, but it would be great if it could see that an unhandled exception occurs, write any unwritten log entries to file, note that an exception happened and log its details, and then allow the app to crash.

If there is some way of catching unhandled exceptions app-wide, I would think it would be something like:

appDidReceiveUnhandledException:(NSException *)exception
{
    //write log to disk
    //append exception info to log file
    //rethrow exception
}

If anyone can give me insight or suggestions on whether or not this is possible, it would be greatly appreciated.

like image 878
mbuc91 Avatar asked Mar 11 '13 21:03

mbuc91


2 Answers

You can add an application-wide unhandled exception handler in your AppDelegate:

void HandleExceptions(NSException *exception) {
    NSLog(@"The app has encountered an unhandled exception: %@", [exception debugDescription]);
    // Save application data on crash
}

Reference it in the AppDelegate didFinishLaunchingWithOptions as:

NSSetUncaughtExceptionHandler(&HandleExceptions);
like image 141
Richard Brown Avatar answered Oct 09 '22 20:10

Richard Brown


You can set your own exception handler by calling NSSetUncaughtExceptionHandler()

You can call it you you app delegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

#ifdef DEBUG
    NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
#endif

...

}

As you can see you need to pass a function pointer to a function like this one:

void uncaughtExceptionHandler(NSException *exception)
{
    NSLog(@"App Crash:\n%@", exception);
    NSLog(@"Stack Trace:\n%@", [exception callStackSymbols]);
}
like image 21
Luca Bernardi Avatar answered Oct 09 '22 18:10

Luca Bernardi