-2

My code ran in the wrong order. The aerror was printed at the beginning, it should be printed at the end.

Here is my code

var aerror :Int?
NSURLConnection.sendAsynchronousRequest(NSURLRequest(URL: url), queue: NSOperationQueue.mainQueue(), completionHandler: { (res, data, error) -> Void in

        let str = NSString(data: data!, encoding: NSUTF8StringEncoding)
        print("\n********\nData\n*******")
        print(str)
        print("\n********\nData\n*******")
        let json = JSON(data: data!)

        aerror = json["Logon"]["error"].int!
        print("\n********\njson\n*******")
        print(json)
        print("\n********\njson\n*******")
    })
    print("\n********\naeeror=\(aerror)")

Here is output


aeeror=nil

********
Data
*******
Optional({"func":"LogonJs","Logon":{"error":2}})
********
Data
*******
********
json
*******
{
  "Logon" : {
    "error" : 2
  },
  "func" : "LogonJs"
}

********
json
*******

I don't know why the aerror was printed first. I Want print the aerror before I return it. Can anyone help me fix it?

2 Answers2

2

NSURLConnection.sendAsynchronousRequest will start an asynchronous request. meaning that there is no way of telling when it will complete at the moment it is called, and once it gets called the next statement will be executed.

The method you are passing it (the completionHandler) is run once the asynchronous request finishes.

In simple terms what is happening is this :

->call sendAsynchronousRequest (with a completionhandler)

->print("\n********\naeeror=\(aerror)") (the asynchronous request is running in the background)

->the asynchronous request finishes

->completionHandler is executed

since you assign aerror in the completion handler, you can print it from the completion handler too.

var aerror :Int?
NSURLConnection.sendAsynchronousRequest(NSURLRequest(URL: url), queue: NSOperationQueue.mainQueue(), completionHandler: { (res, data, error) -> Void in

        let str = NSString(data: data!, encoding: NSUTF8StringEncoding)
        print("\n********\nData\n*******")
        print(str)
        print("\n********\nData\n*******")
        let json = JSON(data: data!)

        aerror = json["Logon"]["error"].int!
        print("\n********\njson\n*******")
        print(json)
        print("\n********\njson\n*******")

        print("\n********\naeeror=\(aerror)")
    })
Timothy Groote
  • 8,614
  • 26
  • 52
  • if you are looking to understand asynchronous vs synchronous better, look here : http://stackoverflow.com/questions/748175/asynchronous-vs-synchronous-execution-what-does-it-really-mean – Timothy Groote Nov 05 '15 at 09:50
1

Everything is working fine... NSURLConnection.sendAsynchronousRequest as stated ub the method name send an asyncronows request with a completion handler that will be executed once the response is received. What your code actually do is:

  1. Create the request
  2. send it moving the entire process of "sending", "waiting" and "managing the response(which means running the completion handler)"on a different thread
  3. Print error on the main thread

This means that once sendAsynchronousRequest is invoked the program doesn't wait for it to finish and execute the compltion handler but keep going and print "aerror". That is the entire purpose of asynchronicity!

If you want your main thread to wait for the termination of the completion handler before continuing the execution I'd suggest the use of a semaphore or the method

sendSynchronousRequest(_:returningResponse:)

Anyway you should use NSURLSession instead of NSURLConnection because this last one is now deprecated.

Freedom
  • 212
  • 2
  • 8