2011-11-02 13 views
6

Estoy usando sendSynchronousRequest para obtener los datos del servidor. Sé que sincrónico esperará hasta que los datos recibidos para esa solicitud.NSURLConnection sendSynchronousRequest - background to foreground

Pero el problema surge cuando el usuario ingresa por error una URL no existente y luego intenta obtener una respuesta. En este caso, si el usuario entra en segundo plano y aparece en primer plano, solo se muestra la pantalla en negro. Solo muestra la barra de estado. Además, no muestra ninguna aplicación de fondo. Tengo que presionar el botón de Inicio para salir de mi aplicación.

En el simulador, después de 1 minuto me muestra el mensaje "Solicitud de tiempo de espera" (Sin bloqueo).

En el dispositivo, en 1 min la aplicación se cuelga.

Cualquier sugerencia. Alguna ayuda. Este es realmente un problema serio en mi aplicación.

Gracias.

+0

¿Usted está consiguiendo algo en la consola antes de estrellarse. – iamsult

+0

publique un registro de fallas por favor. – HelmiB

Respuesta

14

Al igual que dijo Julien, el perro guardián está matando a su aplicación.Para responder algunas preguntas:

  • ¿por qué ocurre esto solo en el simulador? Porque cuando está depurando el watchdog deja su aplicación sola, puede tomar tiempo.
  • ¿por qué ocurre esto solo cuando el usuario ingresa una URL incorrecta? Debido al tiempo de espera del sistema, el sistema seguirá intentándolo durante 60 segundos si no puede encontrar un servidor.
  • por lo que el problema es sincrónico vs asincrónico? No, el problema es el hilo, puede hacer la misma operación en un hilo de fondo, simplemente no lo haga en el hilo principal y el perro guardián lo dejará en paz.
  • ¿Por qué la pantalla aparece negra cuando aparece la aplicación? Recuerde, usted está haciendo el bloqueo de cosas en el hilo principal, el hilo que dibuja ...

la esperanza de que era todo. Avísame si me perdí algo.

0

use la clase ASIHttpRequest en lugar de NSURLConnection, no es nada más que una envoltura alrededor de NSURLConnection y tiene devoluciones de llamada muy simples, también puede establecer el tiempo para completar una solicitud. Por favor, vaya a través de este enlace para más información http://allseeing-i.com/ASIHTTPRequest/

+0

NSURLConnection funciona correctamente para mí, solo en caso de que se bloquee. – JiteshW

+0

ASIHttpRequest no utiliza NSURLConnection en absoluto. Además, ASIHttpRequest ya no se encuentra en desarrollo activo. – hooleyhoop

-1

Creo que la aplicación que falla porque no hay nada de datos cuando el usuario entra mal URL y está usando este 'devuelto' nilNSData hacer telas.

creo que esto va a arreglar el problema

NSData *data=[NSURLConnection sendSynchronousRequest:request 
            returningResponse:&response 
               error:&error]; 
if(data!=nil){ 
    /// 
} else { 
    NSLog(@"NO DATA"); 
} 
0

creo que primero hay que comprobar los datos del usuario si es correcto o no y que sólo si es correcto, envía la solicitud de usuario de otra manera pronta que "por favor introducir los datos correctos" ...

o

cuando su análisis de los datos en respuesta falló. También puede hacer que el protocolo delegue el método, es decir, FinishWithError para que se le ocurra su última IU.

0

prueba este:

#import "ASIHTTPRequest.h" 

//In a method 
[self performSelectorInBackground:@selector(DownLoadImageInBackground:) withObject:imgUrlArr]; 


-(void) DownLoadImageInBackground:(NSArray *)imgUrlArr1 
{ 
    NSURL * url = [Image URL]; 

    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; 
    [request setDelegate:self]; 
    [request startAsynchronous]; 
} 

-(void)requestFailed:(ASIHTTPRequest *)request 

{ 

    NSLog(@"URL Fail : %@",request.url); 

    NSError *error = [request error]; 

     // you can give here alert too.. 
} 

-(void)requestFinished:(ASIHTTPRequest *)request 

{ 

    NSData *responseData = [request responseData]; 
    UIImage *imgInBackground = [[UIImage alloc] 
         initWithData:responseData]; 
    [imageView setImage: imgInBackground]; 

} 

Esto podría ayudarle a: Yo también estoy cargando una serie de imágenes a la vez, por lo que las imágenes que no tienen datos adecuados muestran una pantalla en negro. Para evitar esto, intente cambiar el tamaño de su imagen.

0

Puede verificar la accesibilidad de la URL antes de iniciar la solicitud. Apple tiene Reachability Métodos para hacerlo. Pero es más fácil usar una envoltura. P.ej. ASIReachability.

3

usted debe echar un vistazo a este artículo: https://developer.apple.com/library/ios/#qa/qa1693/_index.html

iOs contiene un organismo de control , si la aplicación se bloquea a mucho tiempo en una operación en el hilo principal, éste se mató. (para más detalles sobre Watchdog: http://en.wikipedia.org/wiki/Watchdog_timer)

Así que si quieres descargar algo, no lo descargues en el hilo principal.

+0

No estoy seguro, pero él no menciona la descarga. La conexión síncrona en el hilo principal puede tener sentido para un inicio de sesión tal vez – suprandr

+1

No creo que tenga sentido usar una conexión síncrona en el hilo principal para la acción de inicio de sesión. Debería ser mejor iniciarla en asincronía, mostrar un indicador de actividad y deshabilitar la interacción del usuario. Le sugiero que cree una clase de inicio de sesión que contenga un método con un bloque de controlador de finalización. (si desea un ejemplo, puede ver la clase TWRequest disponible en iOs 5) – Julien

8

¿Por qué no establecer un tiempo de espera para su conexión?

NSString *urlString = TEST_CONNECTION; 
NSError *error = nil; 
NSHTTPURLResponse *response = nil; 
NSURLRequest *request = [NSURLRequest 
         requestWithURL:[NSURL URLWithString:urlString] 
         cachePolicy:NSURLRequestReloadIgnoringCacheData 
         timeoutInterval:5.0]; 


NSData *conn = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 

Esto debería liberar la espera síncrona después de varios segundos, que debe resolver su problema sin tener que ir con una llamada asincrónica (que a veces no es la solución adecuada)

Sé que esto funciona correctamente porque así es como compruebo si estoy conectado a una VPN determinada (donde las banderas de accesibilidad fallan por completo).

2

RELATE

UIImage *image = [self.imgCache objectForKey:urlString]; 
if(!image){ 
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60.0]; 


    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     NSURLResponse *response = nil; 
     NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; 
     NSLog(@"%@",response); 
     UIImage *img = [UIImage imageWithData:data]; 
     // 

     if(img) 
     { 
      dispatch_sync(dispatch_get_main_queue(), ^{ 
       [self.imgCache setObject:img forKey:urlString]; 
       completionBlock(img); 
      }); 
     } 
    }); 

} 
else{ 
    completionBlock(image); 
}