0

I am using NSURLSession to call my own Webservice which returns JSON, works fine with this code:

func getJSONFromDatabase(){
    let url = NSURL(string: "http://www.myurl/mysqlapi.php")

    let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
        self.json = NSString(data: data!, encoding: NSUTF8StringEncoding)
        print(self.json)
    }
    task.resume()
}

However, it seems that this Task is not executed in the right order, because when i run the following function after the "getJSONFromDatabase" function, the "print" statement in the Task is executed after the "print" statement from the "parseJSON" function.

func parseJSON(){

    let data = self.json.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)

    do {
        let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as! NSArray

        for event in json {
            let name = event["name"]
            let startDate = event["startDate"]


            let dateFormatter = NSDateFormatter()
            dateFormatter.dateFormat = "yyyy-MM-dd"
            let date = dateFormatter.dateFromString(startDate as! String)


            if date != nil {
                self.events.append(Event(name: name as! String, startDate: date!))
            }
            else {
                print("Date is nil")
            }
        }

        for event in self.events {
            print(event.name)
        }
    } catch let error as NSError {
        print("Failed to load: \(error.localizedDescription)")
    }
}

My goal is to save the JSON Data in an Object Array of "Event", but this doesn't seem to work because when i iterate over my "self.events" array, it is empty.

Another problem is: When i split this 2 things like i posted here (2 functions), the "parseJSON" throws an error:

Failed to load: The data couldn’t be read because it isn’t in the correct format.

However, if i add the content of "parseJSON" into the Task of the "getJSONFromDatabase" function, there is no such error, but the array is still empty

Bioaim
  • 928
  • 1
  • 13
  • 26
  • 1
    Two things to fix: 1- `NSURLSession.sharedSession().dataTaskWithURL` is asynchronous so it will execute in the background while on the main thread your app is now calling `parseJSON()`. you'll have to use a "completionHandler" (many examples on SO). 2- `NSURLSession.sharedSession().dataTaskWithURL` gives you *data* but you transform it to a String and then in `parseJSON()` you transform it back to data! Not really efficient nor necessary. Just use the data. – Eric Aya Oct 26 '15 at 11:10
  • 1
    Simple example for NSURLSession: http://stackoverflow.com/questions/31805045/how-to-parse-json-in-swift-2-0-using-nsurlsession And for a completionHandler: http://stackoverflow.com/questions/26569724/nsurlconnection-sendasynchronousrequest-cant-get-variable-out-of-closure – Eric Aya Oct 26 '15 at 11:11
  • call parseJSON in block after print(self.json) – Ashish P. Oct 26 '15 at 11:18

1 Answers1

2

dataTaskWithURL is asynchronous so you your code won't execute from the top down. Use a completion handler to work on the result from the asynchronous call.

func getJSONFromDatabase(success: ((json: String)->())){
    let url = NSURL(string: "http://www.myurl/mysqlapi.php")

    let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
        let json = NSString(data: data!, encoding: NSUTF8StringEncoding)
        success(json: json)
    }
    task.resume()
}

in use

getJSONFromDatabase(success: {json in 
    //do stuff with json
})
Moriya
  • 7,750
  • 3
  • 35
  • 53