1
var arrayData: [String] = []

let bodyData = "parameter=test"

let URL: NSURL = NSURL(string: "Link to php file")
let request:NSMutableURLRequest = NSMutableURLRequest(URL:URL)
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue())
{
    (response, data, error) in
        var output = NSString(data: data, encoding: NSUTF8StringEncoding)

        self.arrayData = self.JSONParseArray(output)

        println(self.arrayData) //Print the result
}

println(self.arrayData) //Print nothing

It look like the new value is only available in sendAsynchronousRequest

Is there a way to make the new value accessible out of the sendAsynchronousRequest ?

Clément Bisaillon
  • 5,037
  • 8
  • 32
  • 53
  • possible duplicate of [Getting data out of the NSURLResponse completion block](http://stackoverflow.com/questions/12352901/getting-data-out-of-the-nsurlresponse-completion-block) - (Didn't you ask (and delete) a very similar question yesterday? http://stackoverflow.com/questions/25513767/variable-in-closure-is-only-available-in-the-closure-swift) – Martin R Aug 27 '14 at 16:35

2 Answers2

3

sendAsynchronousRequest is, as the name suggests, asynchronous. So your final println runs before the request is complete. After the completion handler runs, the new data will be available for all readers (in or outside this handler).

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Ok and how can i fix this? – Clément Bisaillon Aug 27 '14 at 16:18
  • What do you want to do? In the code above, you've already fixed it. You `println()` inside the completion handler, which is run at the correct time. What else are you trying to achieve? – Rob Napier Aug 27 '14 at 16:20
  • I wan't the last println to have the value cause i need this value for my tableView function – Clément Bisaillon Aug 27 '14 at 16:21
  • 1
    That would be a synchronous request (which is available on `NSURLConnection`, but then you will block your entire UI while you wait for the connection. You cannot have a table view wait for a network connection. In the completion handler, tell your cell to tableview to update itself. – Rob Napier Aug 27 '14 at 16:22
1

sendAsynchronousRequest requires a callback passed as argument, which is executed once the asynchronous request has been completed. That's out of the linear flow in your code.

This is what happens:

  1. you call sendAsynchronousRequest
  2. the request is started, but the function returns immediately (it doesn't wait for the request to be completed)
  3. the println line is executed next (last line in your code)
  4. some time later, the asynchronous request is completed, and the closure is executed
  5. the closure assigns a value to self.arrayData

If you want to use the updated value, you have to change the logic a little bit. You can call another closure or a class method (meaning an instance method, not a static one) to post process that variable once it has been set.

Antonio
  • 71,651
  • 11
  • 148
  • 165