You can use a semaphore to block the current thread and wait for your URL session to finish.
Create the semaphore, kick off your URL session, then wait on the semaphore. From your URL session completion callback, signal the semaphore.
You could use a global flag (declare a volatile boolean variable) and poll that from a while loop, but that is less optimal. For one thing, you’re burning CPU cycles unnecessarily.
Here’s a quick example I did using a playground:
import Foundation
var sema = DispatchSemaphore( value: 0 )
class Delegate : NSObject, URLSessionDataDelegate
{
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
{
print("got data \(String(data: data, encoding: .utf8 ) ?? "<empty>")");
sema.signal()
}
}
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config, delegate: Delegate(), delegateQueue: nil )
guard let url = URL( string:"http://apple.com" ) else { fatalError("Could not create URL object") }
session.dataTask( with: url ).resume()
sema.wait()