Подтвердить что ты не робот

Какое правильное использование NSErrorRecoveryAttempting, NSError и UIAlertView в iOS?

У меня возникли проблемы с поиском примеров правильного использования NSError, UIAlertView и NSErrorRecoveryAttempting вместе в iOS. Большая часть документации и примеров, которые я могу найти, охватывает эквивалентную функциональность в OS X, где соответствующие типы поведения интегрированы с помощью Cocoa. Но в iOS кажется необходимым сделать это "вручную", и я не могу найти хороших примеров того, как это делается.

Я очень ценю несколько примеров лучшей практики использования информации в NSError для поддержки попыток восстановления от NSErrors, сообщенных пользователю.

4b9b3361

Ответ 1

Согласно документации Apple:

Важно: класс NSError доступен как для Mac OS X, так и для iOS. Однако API-интерфейсы и механизмы исправления ошибок и устранения ошибок доступны только в наборе приложений (Mac OS X).

Итак, я не уверен, что вы можете использовать NSErrorRecoveryAttempting, даже если он определен в документации (похоже, что это область документов UIKit, которые еще не были обновлены после копирования из Документация AppKit).

Вот как я обрабатываю ошибки в моем коде:

NSError *error = nil;
id result = [SomeClass doSomething:&error];

if (!result) {
    NSLog(@"Do something failed: %@", error);
    UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Something failed!" message:@"There was an error doing something." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
    [alert show];
    return;
}

Ответ 3

Я пытаюсь отразить механизм обработки ошибок AppKit в UIKit, главным образом потому, что я хочу использовать цепочку ответчиков для пересылки ошибок вверх. Я не тестировал это полностью, но на данный момент это выглядит как ниже.

Он довольно хорошо отражает AppKit, но перехваты с записями/списками могут быть переопределены для выполнения пользовательского представления ошибок и восстановления соответственно. Поведение по умолчанию - показать UIAlertView для представления и использовать объект psuedo-NSErrorRecoveryAttempting для восстановления.

@implementation UIResponder (ErrorHandling)

- (void)presentError:(NSError *)error
        completion:(void (^)(BOOL recovered))completion
{
    if (nil == (error = [self willPresentError:error])) {
        return;
    }
    if (self.nextResponder) {
        [self.nextResponder presentError:error completion:completion];
        return;
    }

    // Code to create and show UIAlertView
    // e.g. https://github.com/jayway/CWUIKit/blob/master/Classes/UIAlertView%2BCWErrorHandler.m

    // The UIAlertViewDelegate calls didPresentError...
}

/*
 Override to customise the error object as in AppKit.
 You can also perform your own error presentation, and return nil to terminate the default handling.
 Custom error presentation UI should still call didPresentError... when dismissed
 */
- (NSError *)willPresentError:(NSError *)error
{
    return error;
}

/*
 Override to perform custom error recovery.
 */
- (void)didPresentError:(NSError *)error optionIndex:(NSInteger)optionIndex completion:(void (^)(BOOL recovered))completion
{
    id recoveryAttempter = [error recoveryAttempter];
    if ([recoveryAttempter respondsToSelector:@selector(attemptRecoveryFromError:optionIndex:completion:)]) {
        [recoveryAttempter attemptRecoveryFromError:error optionIndex:optionIndex completion:completion];
    }
}

@end