hectr / ErrorKit

iOS library for making NSError handling easier
MIT License
97 stars 7 forks source link

Crashes if didRecoverSelector is NULL #3

Closed sguillope closed 11 years ago

sguillope commented 11 years ago

Hi,

If I use this code:

[[UIAlertView alertWithTitle:NSLocalizedString(@"Synchronization Failed", nil)
                       error:error] show];

it crashes with the following message: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSInvocation _invocationWithMethodSignature:frame:]: method signature argument cannot be nil'

The problem seems to be that UIAlertView+ErrorKit's alertView:clickedButtonAtIndex: delegate method calls attemptRecoveryFromError:optionIndex:delegate:didRecoverSelector:contextInfo: passing it a nil selector.

I'm still trying to wrap my head around the code and how it's supposed to work so maybe I'm doing something wrong.

Basically here's my code:

  MRErrorBuilder *errorBuilder = [MRErrorBuilder builderWithDomain:IFErrorDomain
                                                              code:-1
                                                       description:NSLocalizedString(@"Synchronization Failed", nil)];
  [errorBuilder setLocalizedFailureReason:NSLocalizedString(@"One or more error(s) occurred during data synchronization.", nil)];
  [errorBuilder setLocalizedRecoveryOptions:@[@"Retry"]];
  MRBlockRecoveryAttempter *recoveryAttempter = [[MRBlockRecoveryAttempter alloc] initWithBlock:^BOOL(NSError *error, NSUInteger recoveryOption) {
    if (0 == recoveryOption)
    {
      [self sync];
      return YES;
    }

    return NO;
  }];
  [errorBuilder setRecoveryAttempter:recoveryAttempter];

  NSError *error = [errorBuilder error];

  [[UIAlertView alertWithTitle:NSLocalizedString(@"Synchronization Failed", nil)
                               error:error] show];
hectr commented 11 years ago

Hi, MRBlockRecoveryAttempter instances cannot be used with [UIAlertView alertWithTitle:error] but with [UIAlertView alertWithTitle:error:delegate:didRecoverSelector:contextInfo:]. MRAlertRecoveryAttempter ones can be used with both methods:

MRErrorBuilder *errorBuilder = [MRErrorBuilder builderWithDomain:IFErrorDomain
                                                            code:-1
                                                     description:NSLocalizedString(@"Synchronization Failed", nil)];
[errorBuilder setLocalizedFailureReason:NSLocalizedString(@"One or more error(s) occurred during data synchronization.", nil)];
[errorBuilder setLocalizedRecoveryOptions:@[@"Retry"]];
MRAlertRecoveryAttempter *recoveryAttempter = [[MRAlertRecoveryAttempter alloc] initWithBlock:^BOOL(NSError *error, NSUInteger recoveryOption, BOOL *finished) {
    if (0 == recoveryOption)
    {
      [self sync];
      return YES;
    }
    return NO;
}];
[errorBuilder setRecoveryAttempter:recoveryAttempter];
NSError *error = [errorBuilder error];
[[UIAlertView alertWithTitle:NSLocalizedString(@"Synchronization Failed", nil)
                               error:error] show];                  
sguillope commented 11 years ago

Yeah I replaced with MRAlertRecoveryAttempter after and it worked. Thanks

hectr commented 11 years ago

Thanks again for your comments.