Instantly share code, notes, and snippets.

Embed
What would you like to do?
creating a recoverable NSError with ease
typedef void (^CFAErrorRecoveryHandler)(NSUInteger optionIndex);
@interface CFANSErrorRecoveyrAttempter : NSObject //<NSErrorRecoveryAttempting>
{
CFAErrorRecoveryHandler _handler;
}
- (id)initWithHandler:(CFAErrorRecoveryHandler)block;
+ (CFANSErrorRecoveyrAttempter *)attempterWithHandler:(CFAErrorRecoveryHandler)block;
@end
@implementation CFANSErrorRecoveyrAttempter
- (id)initWithHandler:(CFAErrorRecoveryHandler)block
{
self = [super init];
if (self) {
_handler = Block_copy(block);
}
return self;
}
- (void)dealloc
{
if (_handler) { Block_release(_handler), _handler = nil; }
[super dealloc];
}
+ (CFANSErrorRecoveyrAttempter *)attempterWithHandler:(CFAErrorRecoveryHandler)block
{
CFANSErrorRecoveyrAttempter *attempter = [[CFANSErrorRecoveyrAttempter alloc] initWithHandler:block];
return [attempter autorelease];
}
#pragma mark NSErrorRecoveryAttempting Protocol
// This will be invoked while the error was presented with -[NSView presentError:modalForWindow:....]
- (void)attemptRecoveryFromError:(NSError *)error optionIndex:(NSUInteger)recoveryOptionIndex delegate:(id)delegate didRecoverSelector:(SEL)didRecoverSelector contextInfo:(void *)contextInfo
{
if (_handler) _handler(recoveryOptionIndex);
}
// This will be invoked while the error was presented with -[NSApp presentError:]
- (BOOL)attemptRecoveryFromError:(NSError *)error optionIndex:(NSUInteger)recoveryOptionIndex
{
if (_handler) _handler(recoveryOptionIndex);
return YES;
}
@end
@interface NSError (RecoverableNSError)
#pragma mark Recoverable Error
/// ---------------------------------
/// @name NSError Creation
/// ---------------------------------
/// Create a recoverable NSError
/// The NSError instance can be presented as a floating panel using -[NSApp presentError:] or as a sheet using -[NSView presentError:...]
/// @param title
/// Briefly describe the error; which is the value for NSLocalizedDescriptionKey
/// @param suggestion
/// Suggest users what to do. The suggestion should be relevant to the recovery options;
/// which is the value for NSLocalizedRecoverySuggestionErrorKey
/// @param options
/// NSArray of NSStrings; which is the value for NSLocalizedRecoveryOptionsErrorKey
/// Basically there should be fewer than 3(or equal to) options and the options obey the exact index sequence as
/// follow. index 0: default option, index 1: alternate option, index 2: other option
/// @param handler
/// recover your error based on the selected option.
/// Please remember that the handler block will not be triggered before
/// the error was presented to the users. (eg: [NSApp presentError:error];)
+ (NSError *)cfa_errorWithTitle:(NSString *)title
recoverySuggestion:(NSString *)suggestion
recoveryOptions:(NSArray *)options
recoveryHandler:(CFAErrorRecoveryHandler)handler;
@end
@implementation NSError (RecoverableNSError)
+ (NSError *)cfa_errorWithTitle:(NSString *)title
recoverySuggestion:(NSString *)suggestion
recoveryOptions:(NSArray *)options
recoveryHandler:(CFAErrorRecoveryHandler)handler
{
NSMutableDictionary *info = [[NSMutableDictionary alloc] initWithCapacity:0];
[info setObject:title forKey:NSLocalizedDescriptionKey];
[info setObject:suggestion forKey:NSLocalizedRecoverySuggestionErrorKey];
[info setObject:options forKey:NSLocalizedRecoveryOptionsErrorKey];
[info setObject:[CFANSErrorRecoveyrAttempter attempterWithHandler:handler] forKey:NSRecoveryAttempterErrorKey];
NSError *error = [NSError errorWithDomain:@"com.cocoafaculty.ErrorDomain" code:0 userInfo:info];
[info release];
return error;
}
@end
@smokyonion

This comment has been minimized.

Owner

smokyonion commented May 5, 2013

Thank you, Mike. Very informative resources. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment