Need help with RMErrorRecoveryAttempter?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

211 Stars 20 Forks Other 4 Commits 2 Opened issues


RMErrorRecoveryAttempter is a class that conforms to the `NSErrorRecoveryAttempting` informal protocol and harnesses the power of blocks allowing you to provide recovery options for an error.

Services available


Need anything else?

Contributors list

# 83,961
3 commits


RMErrorRecoveryAttempter is a class that conforms to the

informal protocol and harnesses the power of blocks allowing you to provide recovery options for an error.

Read the Cocoa Error Handling and Recovery blog post on the Realmac Blog for more error handling tips.

Sample Project

The sample project, RMErrorRecoveryAttempterSampleProject, is an iOS app where locked and unlocked items can be created. If you swipe-to-delete an item that is locked an error is created. The user info dictionary of this error contains an

object which has two recovery options, each with a title and a block object. The titles of these recovery options are used to populate the buttons of an alert and upon tapping a button the corresponding block object is executed. The recovery options return
to inform the caller whether to resend the original message that failed.
RMErrorRecoveryAttempter *errorRecoveryAttempter = [[RMErrorRecoveryAttempter alloc] init];
[errorRecoveryAttempter addRecoveryOptionWithLocalizedTitle:NSLocalizedString(@"Don\u2019t Unlock", @"RMMasterViewController delete locked item error don't unlock recovery option") recoveryBlock:^ BOOL (void) {
    // Do not attempt to recover from the error. Return NO to inform the caller that they should not resend the message that failed.
    return NO;
[errorRecoveryAttempter addRecoveryOptionWithLocalizedTitle:NSLocalizedString(@"Unlock & Delete", @"RMMasterViewController delete locked item error unlock & delete recovery option") recoveryBlock:^ BOOL (void) {
    // Do the required work to recover from the error; unlock the item.
    [item setLocked:NO];
    // Return YES to inform the caller that they should resend the message that failed, not that the original functionality of that message has been performed.
    return YES;
    The `userInfo` dictionary populated with our localized title and messages strings and `RMErrorRecoveryAttempter`. If you have an underlying 
    error, for example an error from a failed `-[NSManagedObjectContext save:]`, you can include it under the `NSUnderlyingErrorKey`.
NSDictionary *userInfo = @{
    NSLocalizedDescriptionKey : NSLocalizedString(@"Cannot delete a locked item", @"RMMasterViewController delete locked item error description"),
    NSLocalizedRecoverySuggestionErrorKey : NSLocalizedString(@"This item cannot be deleted because it is currently locked. Would you like to Unlock & Delete this item?", @"RMMasterViewController delete locked item error recovery suggestion"),
    NSRecoveryAttempterErrorKey : errorRecoveryAttempter,
    NSLocalizedRecoveryOptionsErrorKey : [errorRecoveryAttempter recoveryOptions],
*errorRef = [NSError errorWithDomain:RMErrorRecoveryAttempterSampleProjectErrorDomain code:RMErrorRecoveryAttempterSampleProjectErrorCodeLockedItem userInfo:userInfo];

The alert is presented using the

category. If the
parameter of the completion handler is
then the user chose a recovery path and so the message to delete the item is resent.
- (void)rm_presentError:(NSError *)error completionHandler:(void (^)(BOOL recovered))completionHandler;

On OS X you can use either the following two AppKit methods to present the error.

- (BOOL)presentError:(NSError *)error;
- (void)presentError:(NSError *)error modalForWindow:(NSWindow *)window delegate:(id)delegate didPresentSelector:(SEL)didPresentSelector contextInfo:(void *)contextInfo;


  • Either iOS 5.0 and above, or OS X 10.7 and above
  • LLVM Compiler 4.0 and above
  • ARC

If your project is not using ARC, you’ll need to set the

compiler flag on the
source files. To set these in Xcode, go to your active target and select the Build Phases tab. Expand the Compile Sources section, select the mentioned source files, press Enter, and insert


Please contact James Beith regarding this project, [email protected]


Keith Duncan, @keith_duncan
Damien DeVille, @DamienDeVille
James Beith, @jamesbeith


See the LICENSE file for more info.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.