2017-02-22 59 views
0

你好,我一直在尝试很多,四处寻找,但我无法找到一个很好的解决方案,我的问题。如何等待,直到alamofire图像请求完成

问题是我在一个函数中做了2个请求,并且第一个函数完成了,然后它在主线程上执行了updateUI函数,而不是等待第二个下载完成。

我知道我做错了什么,但在我看来,这两个请求在不同的线程上工作,这就是为什么updateUI只会在第一次下载完成后触发。

是否可以使用dispatchqueue?我不知道如何completionhandlers工作或者悲哀..

我不能看到我有什么要从他们的github页面使用,即时通讯相当新的在斯威夫特。

请不要将其设置为重复。真的很感谢它

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 

} 

回答

1

只需让你的getMovieData功能与完成块。

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

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

}

,然后你可以调用FUNC,在那里你调用它的第二次getMovieData()

+0

是啊,谢谢!但我仍然有同样的问题。我在for循环中为JSON中的每个对象执行第二个请求。我试过叫它,但现在工作。仍然是同样的问题。有没有更好的方法来实现这一点?基本上,我想为每个电影对象,我让我也想下载该电影的海报 – Pr0tonion

1

你的功能应该是这样完成的块更新UI。

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

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

    } 
} 

而且你的函数调用的样子

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

你不必做你的数据业务在你的函数调用btw.You可以做你的东西在你的功能和调用completionHandler()结束了。然后你可以只在函数调用时更新你的UI。