1

I am trying to connect my HTTP server to get data in JSON format. It connects and gets the data properly. I am able to print the data before task.resume() but, it doesn't print after task.resume() Also, the function returns empty object.

I tried saving it into a global variable before task.resume(). So, I can use a getter method to get the data, but still returns empty.

Can you please tell me what I am doing wrong here. Thanks in advance

func getTicketInfo(rDate: String, rName: String) -> NSDictionary {

    var obj = NSDictionary()
    let request = NSMutableURLRequest(URL: NSURL(string: self.host)!)
    request.HTTPMethod = "POST"
    let postString = "&DriverName=\(self.username);&Password=\(self.password);&Function=getTicketPrintInvoiceInfo;&routeName=\(rName);&routeDate=\(rDate);";
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in

        if error != nil {
            print("error=\(error)", terminator: "")
            return
        }

        var parseError: NSError?
        let parsedObject: AnyObject?
        do {
            parsedObject = try NSJSONSerialization.JSONObjectWithData(data!,
                options: NSJSONReadingOptions.AllowFragments)
        } catch let error as NSError {
            parseError = error
            parsedObject = nil
        } catch {
            fatalError()
        }

        obj = (parsedObject as? NSDictionary)!

        //prints the object fine
        print(obj)


    }

    task.resume()
    //prints empty result
    print(obj)
    return obj;


}
pininfarina
  • 123
  • 1
  • 12
  • You cant wait the async method to return the result otherwise it would be a sync method. Add a completion handler to update your UI – Leo Dabus Jan 05 '16 at 20:05
  • 1
    print(obj) is called immediately after task.resume(). It does not wait for it to complete. Where you have //prints the object fine is where you need work with your result. – Alan Scarpa Jan 05 '16 at 20:07
  • This function is not used to update UI, but I guess I need to have it update the class I need to be updated with the data before `task.resume()`. So, since it will return empty, theres no point for this class to have a return type, right? – pininfarina Jan 05 '16 at 20:12
  • But also, Why saving it to a global variable is not working? I have it saved into a global variable before `task.resume()` Then, I try to access it with a getter function from another class, but returns empty. – pininfarina Jan 05 '16 at 20:17

2 Answers2

0

Because this is async request. That line of code you are executing outside of the block has not gotten back any results yet. So, you won't see anything. If you are trying to debug it. The execution order will be like this:

task.resume()
//prints empty result
print(obj)
return obj;

Then, the next execution will be the print(obj) inside. Of course, it will come a little bit slow if networking is not good.

Lucas Huang
  • 3,998
  • 3
  • 20
  • 29
  • Alright. Seems like the function does not wait for the task to complete and returns the obj before it is populated. But, why saving it to a global variable is not working? I have it saved into a global variable before task.resume() Then, I try to access it with a getter function from another class, but returns empty. Also, any way to make it a `sync` request? – pininfarina Jan 05 '16 at 20:38
0

Add this code after first print(obj)

 DispatchQueue.main.async {
    UserDefaults.standard.setValue("\(obj)", forKey: "objGlobal")
 }

This will record the obj to UserDefauls. When you need it, You can grab it from there.

cvdogan
  • 166
  • 1
  • 1
  • 13