2017-02-22 1 views
0

Hallo, ich habe viel versucht und mich auf SO umgeschaut, aber ich kann keine gute Lösung für mein Problem finden.Warten, bis die Alamofire-Bildanforderung fertig ist

Das Problem ist, dass ich 2 Anfragen innerhalb einer Funktion und die erste fertig ist, dann tut updateUI Funktion auf den Haupt-Thread statt warten auf den zweiten Download zu beenden.

Ich weiß, dass ich etwas falsch mache, aber in meinen Gedanken arbeiten die zwei Anfragen auf verschiedenen Threads und deshalb wird updateUI nur ausgelöst, nachdem der erste Download abgeschlossen ist.

Kann die Dispatch-Warteschlange verwendet werden? Ich weiß nicht, wie contractualhandlers entweder traurig arbeiten.

Ich konnte nicht sehen, was ich von ihrer github Seite entweder verwenden muss, ich bin ziemlich neu bei Swift.

Bitte nicht als Duplikat festlegen. würde wirklich zu schätzen es

func getMovieData(){ 

    self.posterLoading.startAnimating() 



     //Set up URL 
     let testCall: String = "https://api.themoviedb.org/3/discover/movie?api_key=935f5ddeed3fb57e&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1&with_genres=12" 

     Alamofire.request(testCall).responseJSON { response in 
      //print(response.request) // original URL request 
      //print(response.response) // HTTP URL response 
      //print(response.data)  // server data 
      //print(response.result) // result of response serialization 

      if let json = response.result.value as? Dictionary<String,AnyObject> { 
       if let movies = json["results"] as? [AnyObject]{ 
        for movie in movies{ 
         let movieObject: Movie = Movie() 

         let title = movie["title"] as! String 
         let releaseDate = movie["release_date"] as! String 
         let posterPath = movie["poster_path"] as! String 
         let overView = movie["overview"] as! String 
         let movieId = movie["id"] as! Int 
         let genre_ids = movie["genre_ids"] as! [AnyObject] 

         movieObject.title = title 
         movieObject.movieRelease = releaseDate 
         movieObject.posterPath = posterPath 
         movieObject.overView = overView 
         movieObject.movieId = movieId 


         for genre in genre_ids{//Genre ids, fix this 
          movieObject.movieGenre.append(genre as! Int) 
         } 

         Alamofire.request("http://image.tmdb.org/t/p/w1920" + posterPath).responseImage { 
          response in 
          debugPrint(response) 

          //print(response.request) 
          //print(response.response) 
          //debugPrint(response.result) 

          if var image = response.result.value { 
           image = UIImage(data: response.data!)! 

           movieObject.poster = image 
          } 
         } 



         self.movieArray.append(movieObject) 
         print("movie added") 

        }//End of for each movie 
        DispatchQueue.main.async(){ 
        print("is ready for UI") 
         self.updateUI() 
        } 

       } 


      } 

    }//End of Json request 


}//End of getmoviedata 

func updateUI(){ 
    uiMovieTitle.text = movieArray[movieIndex].title 
    uiMoviePoster.image = movieArray[movieIndex].poster 

} 

Antwort

1

einfach Ihren getMovieData func mit einem Abschluss-Block machen.

func getMovieData(finished:() -> Void) { 

Alamofire.request(testCall).responseJSON { response in 
    // call me on success or failure 
    finished() 
} 

}

und dann können Sie Ihr Update UI im Abschluss Block der func nennen, wo Sie es zum zweiten Mal getMovieData()

+0

Ja danke! Aber ich habe immer noch das gleiche Problem. Ich mache die zweite Anfrage in einer for-Schleife für jedes Objekt in JSON. Ich habe versucht, es anzurufen, aber jetzt arbeite ich. Immer noch das gleiche Problem. Gibt es einen besseren Weg, dies zu implementieren? Grundsätzlich möchte ich für jedes Filmobjekt, ich möchte auch ein Poster für diesen Film herunterladen – Pr0tonion

1

Ihre Funktion sollte wie folgt aussehen aufrufen.

func getMovieData(completionHandler: @escaping (_ returnedData: Dictionary<String,AnyObject>)-> Void) { 

    Alamofire.request(testCall).response { response in 
     if let JSON = response.result.value { 
      completionHandler(JSON) 
     } 

    } 
} 

Und Ihre Funktionsaufruf aussehen wie

getMovieData(completionHandler: {(returnedData)-> Void in 
    //Do whatever you want with your returnedData JSON data. 
    //when you finish working on data you can update UI 
    updateUI() 
}) 

Sie haben nicht Ihre Datenoperationen in Ihrer Funktion zu tun, rufen btw.You Ihre Sachen in Ihrer Funktion tun können, und rufen Sie die completionHandler() Ende davon. Dann können Sie Ihr UI nur beim Funktionsaufruf aktualisieren.

Verwandte Themen