2012-09-10 11 views
6

Wygląda na to, że nie dostać koncepcję bloków jeszcze całkowicie ...Pobieranie danych z bloku zakończenia NSURLResponse

W moim kodu muszę się dane JSON z asychronous block zostać zwrócone do z metody "outer". Wyszukałem go i odkryłem, że definiując zmienną , zmieniono ją na block.

Ale z jakiegoś powodu zwracany obiekt json jest zerowy. Zastanawiam się, dlaczego?

- (NSMutableDictionary *)executeRequestUrlString:(NSString *)urlString 
{ 
__block NSMutableDictionary *json = nil; 
NSURL *url = [NSURL URLWithString:urlString]; 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 

[request setHTTPShouldHandleCookies:YES]; 
[request setHTTPMethod:@"GET"]; 
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-type"]; 

NSString *cookieString = [self.userDefaults objectForKey:SAVED_COOKIE]; 

[request addValue:cookieString forHTTPHeaderField:@"Cookie"]; 

[NSURLConnection sendAsynchronousRequest:request 
            queue:[NSOperationQueue currentQueue] 
         completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) 
         { 

          NSLog(@"dataAsString %@", [NSString stringWithUTF8String:[data bytes]]); 

          NSError *error1; 
          NSMutableDictionary * innerJson = [NSJSONSerialization 
            JSONObjectWithData:data 
               options:kNilOptions 
               error:&error1]; 
          json = innerJson; 

         }]; 

    return json; 
} 

Odpowiedz

18

Po pierwsze, aby odpowiedzieć na pytanie:

Ale z jakiegoś powodu wrócił obiekt JSON jest nil. Zastanawiam się dlaczego?

Zmienna, którą wracasz, nie została ustawiona w momencie, kiedy ją zwrócisz. Nie można zebrać wyników natychmiast po zwróceniu metody sendAsynchronousRequest:queue:completionHandler:: połączenie musi zakończyć się w obie strony przed oddzwonieniem do bloku i ustawieniem zmiennej json.

Teraz krótka wiadomość na temat tego, co należy z tym zrobić: metoda próbuje przekonwertować wywołanie asynchroniczne na synchroniczne. Staraj się zachować asynchroniczny, jeśli możesz. Zamiast spodziewa się metodę, która zwraca NSMutableDictionary*, uczynić metodę, która przyjmuje blok własnych i przekazać słownika do tego bloku, gdy metoda sendAsynchronousRequest: uzupełnia:

- (void)executeRequestUrlString:(NSString *)urlString withBlock:(void (^)(NSDictionary *jsonData))block { 
    // Prepare for the call 
    ... 
    // Make the call 
    [NSURLConnection sendAsynchronousRequest:request 
            queue:[NSOperationQueue currentQueue] 
         completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { 
     NSLog(@"dataAsString %@", [NSString stringWithUTF8String:[data bytes]]); 
     NSError *error1; 
     NSMutableDictionary * innerJson = [NSJSONSerialization 
      JSONObjectWithData:data options:kNilOptions error:&error1 
     ]; 
     block(innerJson); // Call back the block passed into your method 
     }]; 

} 
+1

To jest absolutnie genialna odpowiedź IMHO! Zabrało mi to trochę czasu, ale było warto. Dzięki, wiele się nauczyłem! – brainray

2

Po wywołaniu sendAsynchronousRequest:queue:completionHandler:, pan poprosił o asynchroniczny prośbę. Więc kolejkuje żądanie i blok i natychmiast zwraca. W pewnym momencie w przyszłości zostanie wysłane żądanie, a po pewnym czasie zostanie uruchomiony blok zakończenia. Ale do tego czasu, return json już dawno działało.

Jeśli chcesz mieć możliwość synchronicznego przesyłania danych, musisz wykonać synchroniczne żądanie. To zawiesi ten wątek, aż się zakończy, więc nie może to być główny wątek.

0

Sprawdzić ciąg podczas przekształcania danych pochodzących z serwera używając poniższego kodu:

NSLog(@"dataAsString %@", [NSString stringWithUTF8String:[data bytes]]); 

jeśli napis jest w odpowiednim formacie JSON, TYLKO wtedy twój obiekt JSON będzie poprawny.

Mam nadzieję, że to hepls !!

Powiązane problemy