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?
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...