2017-08-16 15 views
0

私は以下のコードでいくつか問題があります。 動作しますが、タイミングに問題があります。session.dataタスク同期の問題

最初に私が期待していることを言えば、データのダウンロードが完了してイメージを使用できるようになると完了ハンドラを実行する必要があると思います。しかし、現実は全く異なるようです。私が試してみると、すぐに完了ハンドラが呼び出されます(コンソールで「すべてOK」と見ることができます)、すべてが瞬間的であるかのように。しかし、画像は実際にはずっと後に表示されます。私は何が欠けていますか?

let imageURL = URL(string: myURLString) 
session = URLSession.shared, 
_ = session.dataTask(with: imageURL) {[weak self] 
    (data: Data?, response: URLResponse?, error: Error?) in 
    if error == nil { 
     print("All OK") 
     self?.theImage = UIImage(data: data!) 
     self?.theView.image = self?.theImage 
    } else {print(error!)} 

    DispatchQueue.main.async { 
     self?.activityIndicator.stopAnimating() 
     self?.theView.setNeedsDisplay() 
    } 
    }.resume() 
+0

データがロードされ、サーバーから利用可能になると、ハンドラが再度呼び出されます。また、最後の中かっこの直前にsession.finishTasksAndInvalidate()を追加する必要があります。} .resume() –

+0

OK。 「ハンドラが再び呼び出される」とはどういう意味ですか?すでに呼び出されています。何回も呼ばれることになっていますか? – Michel

+0

データがフェッチされると、コントロールが再びハンドラに到達します。また、自己?theView.image = self?.theImageはメインスレッド上になければなりません。そして、どのバージョンのスウィフトを使っていますか? –

答えて

1

このコードを試すことができますか?

コントロールは、実際には最初の呼び出しでハンドラをに入れてはいけません。そして私はあなたのコードにいくつか間違いがあると思っていますが、私が先に指摘したところでは特に、UIの更新にはメインスレッドが必要です

let session : URLSession 
    let config = URLSessionConfiguration.default 
    var resultFromServer: Any? 
    let responseResultData = [String:Any]() 
    session = URLSession(configuration: config, delegate: nil, delegateQueue: nil) 
    session.dataTask(with: request) { (data, response, error) in 

     if error != nil { 

      DispatchQueue.main.async(execute: { 

       session.invalidateAndCancel() 

      }) 

     }else{ 

      let httpResponse: HTTPURLResponse = response as! HTTPURLResponse 

       do{ 

        resultFromServer = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) 
        if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 || httpResponse.statusCode == 202 || httpResponse.statusCode == 204 || httpResponse.statusCode == 203 { 

         if let respArr = resultFromServer as? [Any]{ 

          //resp is array 


         }else if let respdict = resultFromServer as? [String : Any] { 

          //resp is dict 


         }else{ 

          //resp is something else maybe string, etc 

         } 

        } 
        else { 


         //error status code something like 500, 404, etc 

        } 


       } 

       catch let error as NSError { 

        DispatchQueue.main.async(execute: { 

         session.invalidateAndCancel() 

        }) 
       } 

      } 

     session.finishTasksAndInvalidate() 
     }.resume()