0

I have the following Swift 5 function that calls a PHP script on my server:

func getJSONdata(fileName:String, completion: (_ json:JSON)->()) {
        let session = URLSession(configuration: .ephemeral)
        var jsonData = JSON()

        let myUrl = URL(string: DATABASE_PATH + fileName + "/query.php?queryAll");
        var request = URLRequest(url:myUrl!)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        DispatchQueue.main.async {
            let task = session.dataTask(with: request) { (data, response, error)  in
                if error != nil {
                    print("\(error!.localizedDescription)")
                    return
                }

                // Get data
                jsonData = try! JSON(data: data!)
                // print(jsonData)
            }
            task.resume()
        }//  ./ dispatch aync
        completion(jsonData)
    }

This function is hosted in a separate Swift file, now in my ViewController.swift I call that function as follows:

getJSONdata(fileName: "Users") { (jsonData) in
    print("\(jsonData)")
}

In this case, I'm getting an empty array in my Xcode console, instead, if I uncomment the // print(jsonData) that's inside my getJSONdata() function, the console prints out my JSON data.

Obviously I'm doing something wrong in my getJSONdata() function because I cannot retrieve data by calling in ViewController.swift.

Where is the error in my function?

4
  • 1
    what happens if you move completion(jsonData) under jsonData = try! JSON(data: data!) Commented Jan 16, 2020 at 11:00
  • 1
    you should call the completion handler after you will get a response/data from API. Commented Jan 16, 2020 at 11:01
  • Ok, but this is what I get: i.postimg.cc/g0gz2wvy/error.png Commented Jan 16, 2020 at 11:01
  • Thanks @chirag90, you're right, I also had to add @escaping to my function's declaration. Commented Jan 16, 2020 at 11:07

2 Answers 2

1

Try the below code. Maybe it will help you.

func getJSONdata(fileName:String, completion:@escaping (_ json:JSON)->()) {
            let session = URLSession(configuration: .ephemeral)
            var jsonData = JSON()

            let myUrl = URL(string: DATABASE_PATH + fileName + "/query.php?queryAll");
            var request = URLRequest(url:myUrl!)
            request.httpMethod = "POST"
            request.addValue("application/json", forHTTPHeaderField: "Content-Type")
            DispatchQueue.main.async {
                let task = session.dataTask(with: request) { (data, response, error)  in
                    if error != nil {
                        print("\(error!.localizedDescription)")
                        completion(nil)
                    }

                    // Get data
                    jsonData = try! JSON(data: data!)
                    // print(jsonData)
                    completion(jsonData)
                }
                task.resume()
            }
        }
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, but for some reason, it doesn't work, as shown here: i.postimg.cc/g0gz2wvy/error.png. Anyway, I've posted an answer which is the solutoin to my issue, hope it helps other ones.
Anyway, I had updated my answer. Please check if you've any queries.
0

I've found a solution, I don't know why but if I add @escaping to my function declaration, it works fine.

I also had to move completion(jsonData) below jsonData = try! JSON(data: data!), as suggested by @chirag90.

So, here's the complete function:

func getJSONdata(fileName:String, completion: @escaping (_ json:JSON?) -> Void) {
        let session = URLSession(configuration: .ephemeral)
        var jsonData = JSON()

        let myUrl = URL(string: DATABASE_PATH + fileName + "/query.php?queryAll");
        var request = URLRequest(url:myUrl!)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        DispatchQueue.main.async {
            let task = session.dataTask(with: request) { (data, response, error)  in
                if error != nil {
                    self.simpleAlert("\(error!.localizedDescription)")
                    return
                }

                // Get data
                jsonData = try! JSON(data: data!)
                completion(jsonData)
            }
            task.resume()
        }//  ./ dispatch aync
    }

3 Comments

Thanks, I will, but I can do that only in 2 days, not now :)
Don’t use SwiftyJSON. Take a looks at Codable protocol
Why shouldn't I use SwiftyJSON? It makes me save tons of lines of code

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.