Jacob Wilson
Jacob Wilson

Reputation: 430

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.

Upvotes: 0

Views: 67

Answers (2)

Dave Wood
Dave Wood

Reputation: 13313

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.

Upvotes: 3

Khanh Nguyen
Khanh Nguyen

Reputation: 11134

These two lines

datastring = NSString(data: data!, encoding:NSUTF8StringEncoding) as! String // there is data in here
textView.text = datastring! // datastring is not nill when here

are not run immediately, since they are inside a closure. It's up to Alamofire to decide when to run the closure.

Upvotes: 0

Related Questions