How do I get data (in the form of an array) out of a closure?

I’m trying to return data from a closure so that I can use it outside the closure, but I can’t seem to work it out. I can update the Label in question from within the closure, but I would like to access the array outside the closure.

I’m using a UIView to display the data and the function below is called in viewWillAppear().

Would be grateful for help on this one,

Claire

Here’s the code:

func getInfo() {

    let url = urlWithQuestion(postID)
    
    let session = NSURLSession.sharedSession()
    dataTask = session.dataTaskWithURL(url, completionHandler: {
        data, response, error in
        
        if let error = error where error.code == -999 {
            return  // Search was cancelled
            
        } else if let httpResponse = response as? NSHTTPURLResponse where httpResponse.statusCode == 200 {
            
            if let data = data, dictionary = self.parseJSON(data) {
                self.searchResults = self.parseDictionary(dictionary)
                
                dispatch_async(dispatch_get_main_queue()) {
                    
                
                self.questionLabel.text = self.searchResults[0].question
                    
                }
            }
            
            
        } else {
            print("Failure! \(response!)")
        }
        
        dispatch_async(dispatch_get_main_queue()) {
            
            self.showNetworkError()
            
        }
    })
    
    
    dataTask?.resume()
    

}

In this case you can’t really return any data from your closure. You don’t know when the closure will finish.

When you call dataTask?.resume() the closure will be downloading information. Say that takes as much as three seconds. The getInfo() function will have finished by then. If you wait for the closure to finish by forcing getInfo to wait until there’s an array to return, you’re doing ‘synchronous’ downloading and you’re making everything else in your code freeze while the download is in progress. Making your app unresponsive for three seconds makes for a bad user experience.

Instead you want your app to be responsive, so you make your code event driven. The code in the dispatch_async closure will be called when the download is complete, so that’s where you do something with your array (is searchResults your array?) - perhaps you set the array then you call a refresh function to display the information from the array.

1 Like

Thanks, I get that now :slight_smile: makes sense!

Only question is, how do I refresh a View? I can reloadData for a table, but I’m using a view here. I can’t seem to find anyway of doing that.

Thanks

Claire

Actually, had a complete rethink - I’ll use a nib and table (that way I can use a loading cell too).
Back to the drawing board, but thanks for your help

Claire