Search code examples
iosswiftasynchronousuicollectionviewalamofire

iOS - Asynchronous requests and UI interactions


I have a page that uses Alamofire to retrieve images from Google Image Search API and display them inside a collectionView. Everything works, but when the request is still loading I can't interact at all with the UI, whether it's clicking a button or scrolling the collectionView. Is this normal behavior? I would want the user to at least be able to press the Back button if the request is taking to long, or scroll up and down the collectionView while a new request is being processed.

Alamofire.request(.GET, googleImageApiUrl, parameters: [:]).responseJSON { (request, response, JSON, error) in
    if let results = JSON as? NSDictionary {
        if let images = results["responseData"]!["results"] as? NSArray {
            for image in images {
                let url = NSURL(string: image["unescapedUrl"] as! String)!
                if let data = NSData(contentsOfURL: url) {
                    self.imageData.append(data)
                }
            }

            dispatch_async(dispatch_get_main_queue()) {
                self.collectionView.reloadData()
            }
        }
    }
}

To summarize, once the request is initiated, the user cannot interact with the page in any way until the collectionView has reloaded its data. I figured if the request was asynchronous then I would still have the ability to interact with the UI. Is this an Alamofire limitation, a general limitation, or am I doing something completely wrong?


Solution

  • Alamofire networks asynchronously. No worries there. The problem, though, is probably here:

    let url = NSURL(string: image["unescapedUrl"] as! String)!
    if let data = NSData(contentsOfURL: url) {
    

    If, as I suspect, that URL is a remote URL, then you are now repeatedly networking synchronously. NSData(contentsOfURL:) is not appropriate for fetching stuff across a network on the main thread. If you're going to reach out for more data on the network, use proper networking code - perhaps even using Alamofire some more...