Get Updates By E-mail 

Tutorial: Proper Error Handling In Objective-C on iOS And Mac

  •  
  •  
  •  
  •  
  •  

Editors Note: The following tutorial by James Beith was submitted by Thibault Lemaitre from Realmac Software, and provides a guide and example project on handling errors in Objective-C for iOS and Mac.

For those engineers amongst us, we’re all too familiar with handling errors in the software we develop. Here at Realmac Software we take error handling very seriously simply because it’s just so common place. Whether it be user input, networking, file systems, databases, etc, errors can easily occur. Inadequately handling these error can really impact your app and your users, leaving them with unexpected results, frustration, confusion, loss of their data and crashes.

Doing it wrong

Below is an example of how not to handle an error in your app.

NSError *error = nil;
BOOL didSave = [managedObjectContext save:&error];
if (!didSave) {
// WARNING: Handle the error.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}

What’s so bad? Well, lots! Sure we’ve detected an error has occurred and have logged it to the console, but really that’s not much help at all. It’s especially not much help if your app has shipped; you can’t ask your users to download the iPhone Configuration Utility and dig through the console for these logs when they’ve experienced a problem.

Maybe the above is something quick whilst you’re developing your app. I’d recommend using breakpoints in Xcode instead of NSLog(). Breakpoints are powerful, quick and you you can add them whilst your app is running instead of having to rebuild. I also wouldn’t recommend using a WARNING: to highlight where you need to handle your errors. You should get in to the practice of handling all your errors as you go, the logic plays an important role in the development of your app. Also, leaving a whole bunch of error handling to do at the end is impractical and certainly no fun.

Most importantly we’ve not actually handled the error. We haven’t programatically inspected the error and we most certainly haven’t informed the user or asked them to choose a recovery option.

Recovery Attempting

Recovering from errors is the ultimate goal. We’ve developed our very own RMErrorRecoveryAttempter class which harnesses the power of blocks to provide recovery options for an error. The class conforms to the NSErrorRecoveryAttempting informal protocol.

The NSErrorRecoveryAttempting informal protocol provides methods that allow your application to attempt to recover from an error. These methods are invoked when an NSError object is returned that specifies the implementing object as the error recoveryAttempter and the user has selected one of the error’s localised recovery options.

Let’s assume we’ve an entry object that a user has created. The user then tries to save this entry but because they haven’t set the required date property a save error occurs. To recover from this error we’ve created an RMErrorRecoveryAttempter object that has two recovery options.

RMErrorRecoveryAttempter *errorRecoveryAttempter = [[RMErrorRecoveryAttempter alloc] init];

[errorRecoveryAttempter addCancelRecoveryOption];

[errorRecoveryAttempter addRecoveryOptionWithLocalizedTitle:NSLocalizedString(@"Use Today\u2019s Date", @"RMEntry date error use today's date recovery option") recoveryBlock:^ BOOL (NSError *recoveryError) {
[entry setDate:[NSDate date]];
return YES;
}];

The first is a cancel recovery option that does not attempt to recover from the error and whose recovery block returnsNO. The second recovery option has the title Use Today’s Date and a recovery block that sets the entry’s date to today and then returns YES. The errorRecoveryAttempter is added to the user info dictionary of an NSError object and then presented in an alert. For iOS projects we wrote the category UIResponder+RMErrorRecovery to present the error that includes a completion handler. If the recovered parameter of this completion handler is YES then the user chose a recovery path and so the message to save the entry can be resent.

The class is fit for use in both iOS and OS X projects and we use it throughout all our apps. In Ember, for example, when you share your photos to online services; authenticating against 3rd party services over the network is certainly prone to error conditions beyond our control. We think many people can benefit from what we’ve put together and so we’ve open sourced the code. You can download RMErrorRecoveryAttempter on GitHub, which includes a sample iOS project too. If you’ve questions or comments you can catch me @jamesbeith on Twitter.


The original version of this article was published on the Realmac Software blog.

James Beith is an engineer at Realmac Software, a small, award-winning independent iOS and OS X development studio behind ClearEmber and Rapidweaver


  •  
  •  
  •  
  •  
  •  

Submit A Resource

Have you created a useful tutorial, library or tool for iOS development that you would like to get in front of our 300,000+ monthly page views from iOS developers?

You can submit the url here.

The resources we feel will appeal to our readers the most will be posted on the front page.

Comments