简体   繁体   中英

How to wait until alamofire image request is done

Hello I have been trying alot and looking around on SO, but I cant find a good solution to my problem.

The problem is that i do 2 requests within one function and the first one finishes, then it does updateUI function on the main thread instead of waiting for the second download to finish.

I know that i am doing something wrong but in my mind the two requests work on different threads and that is why updateUI only will trigger after first download is complete.

Is it possible to use dispatchqueue? I dont know how completionhandlers work either sadly..

I couldnt see what i have to use from their github page either, im quite new at Swift.

Please do not set this as duplicate. would really appreciate it

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

}

Just make your getMovieData func with a completion block.

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

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

}

and then you can call your update UI in the completion block of the func, where you calling it the second time getMovieData()

Your function should look like this.

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

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

    }
}

And your function call look like

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

You don't have to do your data operations in your function call btw.You can do your stuff in your function and call the completionHandler() end of it. Then you can update your ui only at function call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM