如何等到 alamofire 图像请求完成
How to wait until alamofire image request is done
你好,我一直在尝试并四处寻找 SO,但我找不到解决问题的好方法。
问题是我在一个函数中执行了 2 个请求,第一个完成后,它在主线程上执行 updateUI 函数,而不是等待第二个下载完成。
我知道我做错了什么,但在我看来,这两个请求在不同的线程上工作,这就是为什么 updateUI 只会在第一次下载完成后触发。
是否可以使用dispatchqueue?我也不知道 completionhandlers 是如何工作的..
我在他们的 github 页面上也看不到我必须使用的东西,我在 Swift 上很新。
请不要将此设置为重复。非常感谢
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
}
只需使您的 getMovieData
函数具有完成块。
func getMovieData(finished: () -> Void) {
Alamofire.request(testCall).responseJSON { response in
// call me on success or failure
finished()
}
}
然后你可以在 func 的完成块中调用你的更新 UI,在那里你第二次调用它 getMovieData()
您的函数应如下所示。
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。
你好,我一直在尝试并四处寻找 SO,但我找不到解决问题的好方法。
问题是我在一个函数中执行了 2 个请求,第一个完成后,它在主线程上执行 updateUI 函数,而不是等待第二个下载完成。
我知道我做错了什么,但在我看来,这两个请求在不同的线程上工作,这就是为什么 updateUI 只会在第一次下载完成后触发。
是否可以使用dispatchqueue?我也不知道 completionhandlers 是如何工作的..
我在他们的 github 页面上也看不到我必须使用的东西,我在 Swift 上很新。
请不要将此设置为重复。非常感谢
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
}
只需使您的 getMovieData
函数具有完成块。
func getMovieData(finished: () -> Void) {
Alamofire.request(testCall).responseJSON { response in
// call me on success or failure
finished()
}
}
然后你可以在 func 的完成块中调用你的更新 UI,在那里你第二次调用它 getMovieData()
您的函数应如下所示。
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。