2011-11-02 23 views
6

Używam sendSynchronousRequest do pobrania danych z serwera. Wiem, że synchroniczne będzie czekać do otrzymania danych dla tego żądania.NSURLConnection sendSynchronousRequest - tło do pierwszego planu

Ale problem pojawia się, gdy użytkownik przez pomyłkę wprowadza jakiś nieistniejący adres URL, a następnie próbuje uzyskać odpowiedź. W takim przypadku, jeśli użytkownik wchodzi w tło, a następnie pojawia się na pierwszym planie, pokazuje tylko czarny ekran. Pokazuje tylko pasek stanu. Również nie pokazuje żadnej aplikacji w tle. Aby wyjść z aplikacji, muszę nacisnąć przycisk Home.

Na symulatorze, Po upływie 1 minuty wyświetli mi się komunikat "Zgłoszenie na żądanie" (bez awarii).

Na urządzeniu, w ciągu 1 minuty aplikacja się zawiesza.

Wszelkie sugestie. Jakaś pomoc. To naprawdę poważny problem w mojej aplikacji.

Dzięki.

+0

się masz coś w konsoli przed upaść. – iamsult

+0

proszę napisać jakiś dziennik awarii. – HelmiB

Odpowiedz

14

Tak jak powiedział Julien, strażnik zabija twoją aplikację.Aby odpowiedzieć na kilka pytań:

  • Dlaczego tak się dzieje tylko na symulatorze? Ponieważ podczas debugowania watchdoga pozostawia samą aplikację, może to trochę potrwać.
  • dlaczego tak się dzieje tylko wtedy, gdy użytkownik wprowadzi zły adres URL? Z powodu przekroczenia limitu czasu system będzie próbował wykonać próbę przez 60 sekund, jeśli nie może znaleźć serwera.
  • , więc problem jest synchroniczny vs asynchroniczny? Nie, problemem jest wątek, możesz wykonać tę samą operację w wątku tła, po prostu nie rób tego w głównym wątku, a watchdog pozostawi Cię w spokoju.
  • dlaczego ekran jest czarny po uruchomieniu aplikacji? Pamiętaj, że robisz blokady na głównym wątku, wątku, który rysuje ...

Nadzieję, że to wszystko. Daj mi znać, jeśli coś przeoczyłem.

0

używać klasy ASIHttpRequest zamiast NSURLConnection, jej nic oprócz owijania wokół NSURLConnection i ma bardzo proste wywołania zwrotne, można również ustawić czas na wykonanie żądania. Proszę przejść przez ten link, aby uzyskać więcej informacji http://allseeing-i.com/ASIHTTPRequest/

+0

NSURLConnection działa poprawnie dla mnie, tylko w powyższym przypadku ulega awarii. – JiteshW

+0

ASIHttpRequest w ogóle nie używa NSURLConnection. Również ASIHttpRequest nie jest już pod aktywnym rozwojem. – hooleyhoop

-1

myślę aplikacja upaść, ponieważ nie otrzymuje żadnych danych, gdy użytkownik wpisze niewłaściwy URL i używasz tego „powrócił” nilNSData zrobić spożywczych.

myślę, że to rozwiąże problem

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

myślę, że najpierw trzeba sprawdzić dane użytkownika, czy jest to poprawne, czy nie, a nie tylko wtedy, gdy jest ona poprawna, wysyła żądanie inaczej szybkiego użytkownika, że ​​„proszę wprowadzić prawidłowe dane”...

lub

gdy parsowanie danych w odpowiedzi nie powiodło się. Możesz również wykonać metodę delegowania protokołu, np. FinishWithError, aby wymyślić ostatni interfejs użytkownika.

0

Spróbuj tego:

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

} 

To może pomóc: Ja również ładowanie wielu obrazów w tym samym czasie, więc obrazy, które nie mają odpowiednie dane pokazują czarny ekran. Aby tego uniknąć, spróbuj zmienić rozmiar obrazu.

0

Możesz sprawdzić osiągalność adresu URL przed rozpoczęciem żądania. Apple ma Reachability Metody, aby to zrobić. Ale łatwiej jest użyć opakowania. Na przykład. ASIReachability.

3

należy spojrzeć do tego artykułu: https://developer.apple.com/library/ios/#qa/qa1693/_index.html

iOS zawiera watchdog, jeśli aplikacja jest zablokowany dużo czasu na operację na głównym wątku, ten zostanie zabity. (Aby uzyskać więcej informacji na temat Watchdog: http://en.wikipedia.org/wiki/Watchdog_timer)

Jeśli chcesz coś pobrać, nie pobieraj go w głównym wątku.

+0

Nie jestem pewien, ale on nie wspomina o pobieraniu. Synchroniczne połączenie w głównym wątku może mieć sens w logowaniu może być – suprandr

+1

Nie wydaje mi się, aby używanie synchronicznego połączenia w głównym wątku miało sens w przypadku akcji logowania. Powinno być lepiej uruchomić asynchronię, wyświetlić wskaźnik aktywności i wyłączyć interakcje użytkownika. Proponuję utworzyć klasę logowania zawierającą metodę z blokiem obsługi zakończeń. (jeśli chcesz mieć przykład, możesz zobaczyć klasę TWRequest dostępną w iOS 5) – Julien

8

Dlaczego nie ustawić limitu czasu dla połączenia?

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

ten powinien zwolnić synchronicznego oczekujące po kilku sekundach, który powinien rozwiązać problem bez wychodzenia z asynchronicznego połączenia (co czasem nie jest właściwym rozwiązaniem)

wiem, że to działa poprawnie, ponieważ tak sprawdzam, czy jestem połączony z pewną VPN (gdzie flagi osiągalności całkowicie zawodzą).

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); 
} 
Powiązane problemy