2013-10-14 11 views
9

Ich versuche, einige Daten von meinem lokalen Knotenserver zu ziehen. Der Server erhält die Get-Anforderung und protokolliert sie, aber aus irgendeinem Grund führt meine iOS-App keinen Code aus, den ich im Completion-Handler habe. Hier ist der Code:NSURLSessionDataTask führt den Completion-Handler-Block nicht aus

- (IBAction) buttonPressed{ 
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1:3000/"]; 
NSURLSessionDataTask *dataTask = 
[self.session dataTaskWithURL:url 
      completionHandler:^(NSData *data, 
           NSURLResponse *response, 
           NSError *error){ 
       nameLabel.text = @"yay!"; 
       /* 
       if (!error){ 
        nameLabel.text = @"noerr"; 
        NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response; 
        if (httpResp.statusCode == 200){ 
         NSError *jsonErr; 

         NSDictionary *usersJSON = 
         [NSJSONSerialization JSONObjectWithData:data 
                 options:NSJSONReadingAllowFragments 
                 error:&jsonErr]; 

         if (!jsonErr){ 
         // nameLabel.text = usersJSON[@"username"]; 
          nameLabel.text = @"nojerr"; 

         } 
         else{ 
          nameLabel.text = @"jsonErr"; 
         } 
        } 
       } 
       else{ 
        nameLabel.text = @"Err"; 
       } 
       */ 
      }]; 
[dataTask resume]; 

}

Wenn das Programm ausgeführt wird, wird die nameLabel nicht geändert "yay". Wenn ich jedoch versuche, das nameLabel vor der NSURLSessionDataTask-Zeile zu ändern, wird es geändert.

+0

Bitte wählen Sie die Antwort aus, wenn es Ihnen geholfen hat. Fühlen Sie sich frei zu kommentieren, wenn Sie noch Fragen bezüglich der Antwort haben. – wigging

Antwort

14

NSURLSessionDataTask läuft in einem Hintergrund-Thread. Um etwas in der Benutzeroberfläche wie Beschriftungen, Schaltflächen, Tabellenansichten usw. zu aktualisieren, müssen Sie dies im Hauptthread tun. Wenn Sie den Beschriftungstext aus dem completionHandler Block aktualisieren möchten, dann müssen Sie wie so das Etikett in den Haupt-Thread aktualisieren:

dispatch_sync(dispatch_get_main_queue(), ^{ 
    nameLabel.text = @"yay!"; 
}); 
12

diese Magie versuchen:

static NSURLSession* sharedSessionMainQueue = nil; 
if(!sharedSessionMainQueue){ 
    sharedSessionMainQueue = [NSURLSession sessionWithConfiguration:nil delegate:nil delegateQueue:[NSOperationQueue mainQueue]]; 
} 

NSURLSessionDataTask *dataTask = 
[sharedSessionMainQueue dataTaskWithURL:url completionHandler:^(NSData *data, 
           NSURLResponse *response, 
           NSError *error){ 
    //now will be on main thread 
}]; 
[dataTask resume]; 

Dies gibt Ihnen das ursprüngliche Verhalten von NSURLConnection mit dem abschließenden Handler im Hauptthread, so dass Sie die UI sicher aktualisieren können. Nehmen wir an, Sie möchten den Download analysieren oder eine umfangreiche Verarbeitung durchführen. In diesem Fall profitieren Sie möglicherweise vom Abschlusshandler im Hintergrundthread der Operation und verwenden dann dispatch_sync als letzten Schritt zum Hauptthread.

+2

+1 - Dies ist ein viel besserer Weg, da Sie dann * optional * zusätzliche Aufgaben für Hintergrundthreads ausführen können und davon ausgehen, dass alles im Hauptthread ausgeführt wird. –

+0

Hmm, Jonathon, wenn Sie diese Methode ALLES im Completion-Block verwenden, wird (kann nur sein) auf dem Hauptthread. – Fattie

+0

Joe er bedeutet, Hintergrundthreads aus dem Hauptthread-Vervollständigungsblock zu erstellen, falls erforderlich. – malhal

Verwandte Themen