2013-10-14 21 views
9

ローカルノードサーバーからデータを取得しようとしています。サーバーはget要求を取得してログに記録していますが、何らかの理由でiOSアプリケーションが完了ハンドラ内にあるコードを実行しません。NSURLSessionDataTaskが完了ハンドラブロックを実行していません

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

}

プログラムが実行されると、nameLabelが「イェーイ」に変更されていません。ここでは、コードです。 NSURLSessionDataTask行の前にnameLabelを変更しようとすると、変更されます。

+0

助けがあれば、以下の回答を選択してください。答えに関連する質問がまだ残っている場合は、お気軽にコメントしてください。 – wigging

答えて

14

NSURLSessionDataTaskはバックグラウンドスレッドで実行されます。ラベル、ボタン、テーブルビューなどのユーザーインターフェイスの内容を更新するには、メインスレッドで行う必要があります。あなたはcompletionHandlerブロックからラベルテキストを更新したい場合、あなたはそのようなメインスレッドにラベルを更新する必要があります。

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

はこの魔法を試してみてください。

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

これはあなたの元の動作を提供しますメインスレッド上の完了ハンドラとNSURLConnectionを組み合わせて、UIを更新しても安全です。しかし、ダウンロードを解析したり、重い処理を行いたい場合は、操作キューのバックグラウンドスレッドの補完ハンドラから利益を得て、最終ステップとしてメインスレッドにdispatch_syncを使用するとよいでしょう。

+2

+1 - バックグラウンドスレッドで追加のタスクを実行し、すべてがメインスレッド上で実行されていると仮定しているので、これはもっと良い方法です。 –

+0

ええと、Jonathonは、このメソッドを完了ブロックで使用すると、メインスレッド上に(唯一あり得る)ことになります。 – Fattie

+0

Joeは、必要に応じてメインスレッド完了ブロックからバックグラウンドスレッドを作成することを意味します。 – malhal

関連する問題