2017-08-16 3 views
0

J'ai quelques problèmes avec le code ci-dessous. Bien que cela fonctionne, il y a un problème de synchronisation. Tout d'abord, laissez-moi vous dire ce que j'attends, je suppose que le gestionnaire de complétion doit être lancé lorsque le téléchargement des données est terminé et que mon image est prête à être utilisée. Mais la réalité semble être très différente. Quand je l'essaie, le gestionnaire de complétion est appelé tout de suite (je peux voir 'Tout OK' dans la console) comme si tout était instantané. Mais l'image est effectivement affichée beaucoup plus tard. Qu'est-ce que je rate?session.dataTask problème de synchronisation

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

Vous devez également avoir ajouté session.finishTasksAndInvalidate() juste avant vos dernières accolades} .resume() –

+0

OK. Que voulez-vous dire par "le gestionnaire sera appelé à nouveau"? Il est déjà appelé. Est censé être appelé plusieurs fois? – Michel

+0

Le contrôle atteint à nouveau le gestionnaire lorsque les données sont extraites. En outre, le self? .theView.image = self? .theImage devrait être sur le fil principal. Et quelle version de Swift utilisez-vous? –

Répondre

1

Pouvez-vous essayer ce code?

Le contrôle ne doit pas aller réellement à l'intérieur le gestionnaire au premier appel. Et je pense qu'il y a quelques erreurs dans votre code aussi bien que je l'ai indiqué plus tôt, en particulier le fil principal est nécessaire pour mise à jour UI. Le gestionnaire sera appelé à nouveau lorsque les données sont chargées et disponibles à partir du serveur

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()