2011-05-11 9 views
12

Non riesco a trovare esempi del modo corretto di utilizzare NSError, UIAlertView e NSErrorRecoveryAttempting insieme su iOS. La maggior parte della documentazione e degli esempi che riesco a trovare riguardano la funzionalità equivalente su OS X, dove i comportamenti rilevanti sono integrati da Cocoa. Ma in iOS sembra necessario farlo "a mano", e non riesco a trovare buoni esempi di come è fatto.Qual è l'uso corretto di NSErrorRecoveryAttempting, NSError e UIAlertView in iOS?

Apprezzerei molto alcuni esempi di best practice sull'utilizzo delle informazioni in NSError per supportare i tentativi di ripristino da NSErrors segnalati all'utente.

+0

A un certo punto ho scritto codice per fare esattamente questo (gestisco presentando NSError usando UIAlertView ecc.), Ma devo ancora vedere un errore che in realtà ha un 'recoveryAttempter' quindi non so se è davvero giusto. – Anomie

risposta

6

Secondo la documentazione di Apple:

Importante: La classe NSError è disponibile sia su Mac OS X e iOS. Tuttavia, le API e i meccanismi di riconoscimento degli errori e di ripristino degli errori sono disponibili solo nel Kit di applicazione (Mac OS X).

Quindi, non sono sicuro se è possibile utilizzare NSErrorRecoveryAttempting anche se sembra essere definito nella documentazione (sembra che questa è una zona dei documenti UIKit che non sono ancora stati aggiornati dopo essere stati copiati dalla documentazione di AppKit).

Ecco come gestire gli errori nel mio codice:

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; 
} 
+2

Poiché NSErrorRecoveryAttempting è un protocollo informale, tutto ciò che è necessario per la conformità di un oggetto è l'implementazione di questi due metodi. E NSError su iOS certamente contiene le proprietà e le costanti necessarie. A quanto pare, il commento di Apple si riferisce solo ai metodi specifici di appkit descritti [qui] (http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ErrorHandlingCocoa/ErrorRespondRecover/ErrorRespondRecover.html) e [qui] (http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ErrorHandlingCocoa/HandleReceivedError/HandleReceivedError.html). – Anomie

+0

NSErrorRecoveryAttempting funziona perfettamente su iOS. Puoi vederlo nell'intestazione NSError.Quello che manca è la possibilità di passare un errore ad un avviso come su MacOS X - questo è molto facile da fare aggiungendo una categoria su UIAlertView che esegue il recupero degli errori e ci sono diversi esempi su come farlo. – quellish

0

sto cercando di rispecchiare il meccanismo di gestione degli errori di AppKit in UIKit, soprattutto perché voglio approfittare della catena risponditore per inoltrare gli errori verso l'alto. Non l'ho testato completamente, ma al momento sembra di seguito.

Rispecchia AppKit abbastanza da vicino, ma gli hook di volontà/di fatto possono essere sovrascritti per eseguire rispettivamente la presentazione e il ripristino degli errori personalizzati. Il comportamento predefinito consiste nel mostrare un UIAlertView per la presentazione e utilizzare un oggetto psuedo-NSErrorRecoveryAttempting per il ripristino.

@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 
Problemi correlati