Your FlightService functions need to be doing the async tasks and using completionHandlers to pass the response back to the calling code.
See the below code
// model
class Flight {}
// flight service
class FlightService: NSObject
{
func getFlightData(airportCode: String, minutesBehind: Int, minutesAhead: Int, completion: @escaping (Bool, [Flight]?) -> Void) {
// main thread still
let url = NSURL(string: "http://..........")!
let request = NSMutableURLRequest(url: url as URL)
request.httpMethod = "Get"
// This always runs in the background, so no need to specifically put it there
let task = URLSession.shared.dataTask(with: request as URLRequest){ data,response,error in
guard error == nil else {
completion(false, nil)
return
}
// parse response data instead I'll create blank array
var parsedFlights = [Flight]()
completion(true, parsedFlights)
}
task.resume()
}
}
// USAGE
@IBAction func searchAction(_ sender: Any) {
let airportName: String = "airportCode.text!"
let minutesBefore: String = "minutesBehind.text!"
let minutesAfter: String = "minutesAhead.text!"
FlightWebService().getFlightData(airportCode: airportName, minutesBehind: minutesBefore, minutesAhead: minutesAfter) { [weak self] success, flights in
// we are still in a background thread here and would need to Dispatch to the main thread to update any UI
guard let strongSelf = self, success else { return }
print(flights.count)
strongSelf.flightSearchResults = flights
strongSelf.performSegue(withIdentifier: "goToSearch", sender: self)
}
}
NSURLSession
always runs in the background thread so there is no need to manually dispatch into it.
In the searchFunction once the completionHandler returns we are still running in the background thread at this point but we have parsed our response data and passed back the flight data, if we need to update any UI from here we would need to dispatch into the main thread.
NOTE: you should generally also use a weak self
in a closure because during the async task, we may have lost the reference to the calling class (self).