2010-01-15 14 views
20

¿cómo puedo hacer un mejor manejo de errores con NSURLConnection sendSynchronousRequest? ¿Hay alguna manera puedo aplicarmanejo de errores con NSURLConnection sendSynchronousRequest

- (void)connection:(NSURLConnection *)aConn didFailWithError:(NSError *)error 

tengo una cola NSOperation que está recibiendo datos en segundo plano es por eso que tengo solicitud de sincronización. y si tengo que implementar una solicitud asíncrona, ¿cómo puedo esperar para que la solicitud se complete? porque ese método no puede avanzar sin datos.

Respuesta

30

-sendSynchronousRequest: returningResponse: error: le da una forma de obtener un error allí mismo en el método. Ese último argumento es realmente (NSError **) error; es decir, un puntero a un puntero NSError. Prueba esto:

NSError  *error = nil; 
NSURLResponse *response = nil; 

[NSURLConnection sendSynchronousRequest: req returningResponse: &response error: &error]; 

if (error) {...handle the error} 
+8

Asegúrese de inicializar el error y la respuesta a cero, que estaba recibiendo errores EXC_BAD_ACCESS hasta que encontré esta respuesta. Gracias +1! – keegan3d

+9

Realmente necesita probar el resultado, antes de probar el error. De la documentación * "Devuelve nil si no se pudo crear una conexión o si la descarga falla" * http://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference .html # // apple_ref/occ/clm/NSURLConnection/sendSynchronousRequest: returningResponse: error: – ohhorob

+5

Cocoa [garantías] (http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/CreateCustomizeNSError/CreateCustomizeNSError .html # // apple_ref/doc/uid/TP40001806-CH204-SW1) que si el método falla, el objeto de error será válido; no garantiza que el objeto de error será 'nil' si el método tiene éxito. Debe verificar el valor de retorno directo antes de usar el error. –

55

no confiaría en ser el error no nula para indicar que se ha producido un error.

He estado utilizando la comprobación de errores como se describe en la respuesta de Ben, pero creo que está generando errores falsos positivos/espurios en algunas circunstancias.

Según este SO answer, estoy cambiando para usar el resultado del método para determinar el éxito/fracaso. Y luego (y solo entonces) revisa el puntero de error para detalles de la falla.

NSError *requestError; 
NSURLResponse *urlResponse = nil; 
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError]; 
/* Return Value 
    The downloaded data for the URL request. Returns nil if a connection could not be created or if the download fails. 
*/ 
if (response == nil) { 
    // Check for problems 
    if (requestError != nil) { 
     ... 
    } 
} 
else { 
    // Data was received.. continue processing 
} 

Este enfoque evitará reaccionar a un error que ocurrió en el proceso de descarga que no provocó su error. Creo que es posible que a medida que se descargue pueda encontrar errores no críticos que se manejen dentro del marco, y tienen el efecto secundario de configurar el puntero de error con un objeto de error.

Por ejemplo, he estado recibiendo errores POSIX informados por usuarios que han descargado la aplicación que parece haber ocurrido en el procesamiento de la conexión URL.

Este código se utiliza para informar del error:

NSString *errorIdentifier = [NSString stringWithFormat:@"(%@)[%d]",requestError.domain,requestError.code]; 
[FlurryAPI logError:errorIdentifier message:[requestError localizedDescription] exception:nil]; 

Y el error aparece reportada como:

Platform: iPhone 
Error ID: (NSPOSIXErrorDomain)[22] 
Msg: Operation could not be completed. Invalid argument 

mapeo que volver ..

requestError.domain = NSPOSIXErrorDomain 
requestError.code = 22 
[requestError localizedDescription] = Operation could not be completed. Invalid argument 

todo lo que he sido capaz de desenterrar, es que el código de error 22 es EINVAL, pero eso no ha dado ningún detalle adicional.

Otros errores que recibo son del dominio NSURL, que estoy totalmente de esperar bajo diversas condiciones de la red:

NSURLErrorTimedOut 
NSURLErrorCannotConnectToHost 
NSURLErrorNetworkConnectionLost 
NSURLErrorNotConnectedToInternet 
+others 
+0

Usar el resultado para determinar el éxito/fracaso es la única forma correcta de hacerlo y está exactamente documentado de esa manera. Sus primeros dos párrafos podrían reemplazarse con "La respuesta de Ben es incorrecta, esta es la forma correcta de hacerlo". :) – bbum

Cuestiones relacionadas