2010-12-29 9 views
10

Dies ist aus dem Beispielcode Apple:Wie behandelt NSFetchedResultsController Abruffehler?

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(); 
} 

Ich frage mich, ob es wirklich notwendig ist immer die App beenden? Wie können Sie "diese Implementierung durch Code ersetzen, um den Fehler entsprechend zu behandeln"? Und wie würden Sie "wiederherstellen von dem Fehler"?

Irgendwelche Vorschläge geschätzt würde, Fabian

+2

Der 'abbrechen()' Ruf ist da als Panikmache. – BoltClock

+1

Jedenfalls hängt es davon ab, was der abgerufene Ergebnis-Controller sucht. Das bedeutet für verschiedene Dinge in Ihrer App, dass Sie den Fehler anders behandeln möchten. Ihre Frage zu * was genau zu tun ist * mit diesem 'NSError'-Objekt bleibt jedoch gültig, also +1 – BoltClock

+0

Ich neige dazu, eine Warnung auf dem Bildschirm zu erhalten, die die lokalisierte Beschreibung des NSError zeigt, so dass der Benutzer etwas an den technischen Support melden muss. –

Antwort

7

Nun, offenbar hat niemand eine andere (bessere?) Lösung, so ist hier mein Ansatz:

In meinem AppController Ich habe eine Instanzvariable errorString und diese Methode:

- (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]; 
} 

der UIAlertView Delegat zeigt eine MFMailComposeViewController mit dem errorString im kühlen Courier-Schriftart :) wenn "Send Report" abgegriffen wird. Andernfalls ruft es 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:@"[email protected]"]; 
     [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(); 
    } 
} 

und die MFMailComposeViewControllerDelegate zeigt eine zweite UIAlertView mit nur einer Taste (offensichtlich die Taste hat den Index 0, so dass es abort() nennen):

- (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

Haben Sie diese Lösung in der Produktion verwendet? Haben Sie schon einmal E-Mails bekommen? – abellina

+0

Ich habe es in der Produktion verwendet und ich habe zwei E-Mails bekommen. – fabian789

+1

@ fabian789 Noch hilfreiche Jahre später, danke! Sie können auch '[MFMailComposeViewController canSendMail]' 'verwenden, um zu bestimmen, ob das Gerät für das Senden von E-Mails konfiguriert ist (und eine Fallback-Warnmeldung bereitstellt, falls nicht), bevor Sie MFMailComposeViewController initialisieren. – JWK

Verwandte Themen