开发者

How to handle NSFetchedResultsController fetch errors?

开发者 https://www.devze.com 2023-02-01 21:40 出处:网络
This is from the Apple sample code: if (![fetchedResultsController_ performFetch:&error]) { /* Replace this implementation with code to handle the error appropriately.

This is from the Apple sample code:

if (![fetchedResultsController_ performFetch:&error]) {
     /*
      Replace this implementation with code to handle the error appropriately.
      ...
      If it is not possible to recover from the error, ...
      */
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

I am wondering whether it is really necessary to always terminate the app? How could you "replace this implementation with code to handle the error appropriately"? And how would you "recover from the error"?

Any 开发者_运维技巧suggestions would be appreciated, Fabian


Well, apparently nobody has another (better?) solution, so here is my approach:

In my AppController I added a instance variable errorString and this method:

- (void)presentCoreDataError:(NSError *)error
                    withText:(NSString *)text
{
    NSMutableString *localErrorString = [[NSMutableString alloc] init];

    [localErrorString appendFormat:@"Failed to %@: %@", text, [error localizedDescription]];

    NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
    if(detailedErrors != nil && [detailedErrors count] > 0) {
        for(NSError* detailedError in detailedErrors) {
            [localErrorString appendFormat:@"- Detail: %@", [detailedError userInfo]];
        }
    } else {
        [localErrorString appendFormat:@"- %@", [error userInfo]];
    }

    UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"Failed to %@", text]
                                                     message:@"Please send a report to the developer."
                                                    delegate:self
                                           cancelButtonTitle:@"Cancel"
                                           otherButtonTitles:@"Send Report", nil] autorelease];
    [alert show];

    self.errorString = localErrorString;
    [localErrorString release];
}

The UIAlertView delegate displays an MFMailComposeViewController with the errorString in the cool courier font :) if "Send Report" is tapped. Otherwise it calls abort():

- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {     // Send Report
        MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
        picker.mailComposeDelegate = self;
        NSArray *toRecipients = [NSArray arrayWithObject:@"first@example.com"];
        [picker setToRecipients:toRecipients];
        [picker setSubject:@"Error Report"];
        [picker setMessageBody:[NSString stringWithFormat:@"The application crashed with the following error:<br><br><FONT FACE=%@> %@ </FONT>", 
                                @"courier", errorString] 
                        isHTML:YES];

        [navigationController presentModalViewController:picker animated:YES];
        [picker release];
    } else {
        abort();
    }
}

And the MFMailComposeViewControllerDelegate displays a second UIAlertView with only one button (obviously the button has index 0, so it will call abort()):

- (void)mailComposeController:(MFMailComposeViewController *)controller
          didFinishWithResult:(MFMailComposeResult)result
                        error:(NSError *)error
{
    [navigationController dismissModalViewControllerAnimated:YES];

    NSMutableString *messageString = [[NSMutableString alloc] init];

    if (result == MFMailComposeResultSent) {
        [messageString appendFormat:@"Thanks! "];
    }

    [messageString appendFormat:@"The application has to quit now."];
    UIAlertView *abortAlert = [[[UIAlertView alloc] initWithTitle:nil
                                                          message:messageString
                                                         delegate:self
                                                cancelButtonTitle:@"OK"
                                                otherButtonTitles:nil] autorelease];

    [abortAlert show];

    [messageString release];
}
0

精彩评论

暂无评论...
验证码 换一张
取 消