2011-11-02 9 views
6

Sto usando sendSynchronousRequest per ottenere i dati dal server. So che sincrono aspetterà fino a quando i dati ricevuti per quella richiesta.NSURLConnection sendSynchronousRequest - background to foreground

Ma il problema si presenta quando l'utente per errore inserisce un URL non esistente e tenta di ottenere una risposta. In questo caso, se l'utente passa allo sfondo e in primo piano mostra solo lo schermo nero. Mostra solo la barra di stato. Inoltre non mostra alcuna applicazione in background. Devo premere il tasto Home per uscire dalla mia applicazione.

Sul simulatore, dopo 1+ minuto viene visualizzato il messaggio "Richiesta di timeout" (nessun arresto).

Sul dispositivo, entro 1 min l'applicazione si arresta in modo anomalo.

Qualsiasi suggerimento. Qualsiasi aiuto. Questo è davvero un problema serio nella mia app.

Grazie.

+0

Sei sempre qualcosa in console prima di schiantarsi. – iamsult

+0

pubblica qualche registro di crash, per favore. – HelmiB

risposta

14

Proprio come ha detto Julien, il cane da guardia sta uccidendo la tua app.Per rispondere ad alcune domande:

  • perché ciò accade solo sul simulatore? Perché quando esegui il debug del watchdog lascia la tua app da solo, può volerci del tempo.
  • perché ciò accade solo quando l'utente inserisce un URL errato? A causa del timeout di sistema, il sistema continuerà a provare per 60 secondi se non riesce a trovare un server.
  • quindi il problema è sincrono vs asincrono? No, il problema è il thread, puoi fare la stessa operazione in un thread in background, semplicemente non farlo sul thread principale e il watchdog ti lascerà in pace.
  • perché lo schermo è nero quando viene visualizzata l'app? Ricorda, stai facendo blocchi sul thread principale, il thread che disegna ...

Speranza che era tutto. Fammi sapere se mi sono perso qualcosa.

0

utilizza la classe ASIHttpRequest invece di NSURLConnection, non è altro che wrapper attorno a NSURLConnection e dispone di callback molto semplici, è inoltre possibile impostare il tempo per completare una richiesta. Si prega di passare attraverso questo link per maggiori informazioni http://allseeing-i.com/ASIHTTPRequest/

+0

NSURLConnection funziona correttamente per me, solo nel caso di cui sopra si blocca. – JiteshW

+0

ASIHttpRequest non utilizza affatto NSURLConnection. Anche ASIHttpRequest non è più in fase di sviluppo attivo. – hooleyhoop

-1

Credo che l'applicazione crash perché non c'è niente di dati quando l'utente entra sbagliato URL e si sta utilizzando questo 'tornato' nilNSData di fare gli animali.

penso che questo risolverà il vostro problema

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

Credo che bisogna prima di verificare i dati degli utenti se sia corretto o meno e rispetto solo se è corretto, invia la richiesta altrimenti richiesta utente che "si prega di inserire i dati corretti" ...

o

quando il parsing dei dati in risposta non è riuscita. È anche possibile eseguire il metodo delegate del protocollo i.e FinishWithError in modo da ottenere l'ultima interfaccia utente.

0

provare questo:

#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]; 

} 

Questo potrebbe aiutare: Sto anche il caricamento di un numero di immagini in una sola volta, in modo da immagini che non hanno dati corretti mostrano uno schermo nero. Per evitare ciò, prova a ridimensionare la tua visualizzazione di immagini.

0

È possibile verificare la raggiungibilità dell'URL prima di avviare la richiesta. Apple ha Reachability metodi per farlo. Ma è più facile usare un wrapper. Per esempio. ASIReachability.

3

si dovrebbe dare un'occhiata a questo articolo: https://developer.apple.com/library/ios/#qa/qa1693/_index.html

iOs contiene un watchdog, se l'applicazione è bloccata per molto tempo su un'operazione sul thread principale, questo sarà ucciso. (per maggiori dettagli su Watchdog: http://en.wikipedia.org/wiki/Watchdog_timer)

Quindi, se si desidera scaricare qualcosa, non scaricarlo sul thread principale.

+0

Non sono sicuro, ma non menziona il download. La connessione sincrona sul thread principale può avere senso per un login forse – suprandr

+1

Non penso che abbia senso utilizzare la connessione sincrona sul thread principale per l'azione di login. Dovrebbe essere preferibile lanciarlo in modo asincrono, visualizzare un indicatore di attività e disabilitare l'interazione dell'utente. Ti suggerisco di creare una classe di login contenente un metodo con un blocco di gestione del completamento. (se vuoi un esempio, puoi vedere la classe TWRequest disponibile in iOs 5) – Julien

8

Perché non impostare un timeout per la connessione?

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

Questo dovrebbe rilasciare l'attesa sincrona dopo un certo numero di secondi, che dovrebbe risolvere il problema senza andare con una chiamata asincrona (che a volte non è la soluzione corretta)

So che questo funziona correttamente perché è così che controllo se sono connesso a una determinata VPN (dove i flag di raggiungibilità falliscono totalmente).

2

RIGUARDANO

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