cplater
cplater

Reputation: 33

Wait for a network call to complete before returning a value

I'm trying to get and return some (json) data from a network call, and I'm wondering if there is a better way to wait for the network data other than just and empty loop.

Here's my code:

func sendAPIRequest(endpoint:String) -> JSON?
{
    var json = JSON("")
    let request = NSMutableURLRequest(URL: NSURL(string: "https://host.com/".stringByAppendingString(endpoint))!)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
        guard error == nil && data != nil else {                                                          // check for fundamental networking error
            print("error=\(error)")
            return
        }
        if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {           // check for http errors
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
        }
        json = JSON(data: data!)
    }
    task.resume()
    while (json == "") {
        // Wait
    }
    return json
}

I remember trying something similar in Objective-C which resulted in an infinite loop at run time.

Upvotes: 0

Views: 1350

Answers (1)

Mtoklitz113
Mtoklitz113

Reputation: 3878

You need a completion handler if you want to return values from an async operation. dataTaskWithRequest is an async process. Do this:

func sendAPIRequest(endpoint:String, complete: (JSON) -> ())
{
    var json = JSON("")
    let request = NSMutableURLRequest(URL: NSURL(string: "https://host.com/".stringByAppendingString(endpoint))!)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
        guard error == nil && data != nil else {                                                          // check for fundamental networking error
            print("error=\(error)")
            return
        }
        if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {           // check for http errors
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
json = JSON(data: data!)
complete(json)
        }

    }
    task.resume()

}

And then call it like so:

sendAPIRequest(<your endpoint string>) { theJSON in
//Use the Json value how u want
}

Upvotes: 3

Related Questions