10

これはAppleのサンプルコードからのものです。

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

常にアプリを終了することが本当に必要なのかしら?「この実装をコードに置き換えて、エラーを適切に処理する」にはどうすればよいでしょうか。そして、どのようにして「エラーから回復」しますか?

何か提案をいただければ幸いです、Fabian

4

1 に答える 1

7

まあ、どうやら誰も別の(より良い?)解決策を持っていないので、ここに私のアプローチがあります:

私の AppController では、インスタンス変数errorStringとこのメソッドを追加しました:

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

"Send Report" がタップされた場合、デリゲートはクールな Courier フォントで :)をUIAlertView表示しますMFMailComposeViewControllererrorStringそれ以外の場合は、次のように呼び出します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();
    }
}

そして、ボタンが 1 つだけMFMailComposeViewControllerDelegateの秒が表示されUIAlertViewます (明らかに、ボタンのインデックスは 0 であるため、 が呼び出されます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];
}
于 2010-12-30T11:57:45.323 に答える