2013-10-14 3 views
9

J'essaie d'extraire des données de mon serveur de noeud local. Le serveur reçoit la demande get et la consigne, mais pour une raison quelconque, mon application iOS n'exécutera pas le code que j'ai dans le gestionnaire d'achèvement. Voici le code:NSURLSessionDataTask n'exécutant pas le bloc du gestionnaire d'achèvement

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

}

Lorsque le programme est exécuté, le nameLabel ne change pas à "yay". Cependant, si j'essaie de changer le nomLabel avant la ligne NSURLSessionDataTask, cela change.

+0

Veuillez sélectionner la réponse ci-dessous si elle vous a aidé. N'hésitez pas à commenter si vous avez encore des questions liées à la réponse. – wigging

Répondre

14

NSURLSessionDataTask s'exécute dans un thread d'arrière-plan. Pour mettre à jour quoi que ce soit dans l'interface utilisateur, tels que les étiquettes, les boutons, les vues de table, etc., vous devez le faire sur le thread principal. Si vous souhaitez mettre à jour le texte de l'étiquette du bloc completionHandler alors vous devez mettre à jour l'étiquette dans le thread principal comme ceci:

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

essayer cette magie:

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

Cela vous donne le comportement d'origine de NSURLConnection avec le gestionnaire de fin sur le thread principal afin que vous puissiez mettre à jour l'interface utilisateur en toute sécurité. Cependant, disons que vous souhaitez analyser le téléchargement ou effectuer un traitement intensif, dans ce cas, vous pouvez bénéficier du gestionnaire de complétion sur le thread d'arrière-plan de la file d'attente, puis utiliser dispatch_sync comme tâche finale.

+2

+1 - C'est un bien meilleur moyen, car vous pouvez ensuite * optionnellement * choisir d'exécuter des tâches supplémentaires sur les threads d'arrière-plan, et supposer que tout est exécuté sur le thread principal. –

+0

Hmm, Jonathon si vous utilisez cette méthode TOUT dans le bloc d'achèvement, sera (ne peut être) sur le thread principal. – Fattie

+0

Joe, il signifie créer des threads de fond à partir du bloc d'achèvement de thread principal si nécessaire. – malhal

Questions connexes