Jacob Wilson Jacob Wilson - 7 months ago 12
Swift Question

Swift Variable Values and Functions

I have a piece of code in which an optional is initialized and is then assigned a value in a function but is

nill
when unwrapped?

var datastring: String?
Alamofire.request(.POST, "https://example.url/request", parameters: parameters) .response { request, response, data, error in
datastring = NSString(data: data!, encoding:NSUTF8StringEncoding) as! String // there is data in here
// textView.text = datastring! datastring is not nill when here
}
textView.text = datastring! // datastring is nill when here


This is not Alamofire specific. I have come accross this issue when using native Swift methods. What am I doing wrong and why does Swift work this way?

PS. I'm still learning :)

EDIT: Thank you to all who helped me. To clarify the problem, it was a question of transferring a variable's value from an asynchronous thread to the main thread. I just didn't know how to word that.

Answer

You're updating the datastring variable in a closure. That's code that is passed to Alamofire to be executed later (microseconds later perhaps). So the line assigning datastring to the textView happens first, before the closure executes.

Try this instead:

var datastring: String?

Alamofire.request(.POST, "https://example.url/request", parameters: parameters).response { request, response, data, error in
    datastring = NSString(data: data!, encoding: NSUTF8StringEncoding) as! String

    dispatch_async(dispatch_get_main_queue()) {
        textView.text = datastring
    }
}  

Using the dispatch_async call ensures the UI update happens on the main thread.

It's possible that network request won't happen for several seconds (or longer), so you may want to update the UI with a temporary string so the user sees something while waiting.