I'm trying to write my first Swift command line tool. The tool creates a network request and I want to print the progress of the request using URLSessionTaskDelegate.
The basic URL request code is here:
EDIT: updating more complete example
class ApiSession: NSObject, URLSessionTaskDelegate {
func makeRequest(request: URLRequest,
callback: @escaping (Data?, URLResponse?, Error?) -> Void) {
let urlSession = URLSession(configuration: .default, delegate: self, delegateQueue: .main)
let task = urlSession.dataTask(with: request, completionHandler: callback)
task.resume()
urlSession.finishTasksAndInvalidate()
}
func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) {
print("WAITING")
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
print("TEST TEST")
}
func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) {
print("BECAME INVALID")
}
}
func main() throws {
let apiSession = ApiSession()
let request = URLRequest(url: URLComponents(string: "http://example.com/")!.url!)
let sem = DispatchSemaphore(value: 0)
apiSession.makeRequest(request: request) { (data, response, err) in
if (err != nil) {
print(err.debugDescription)
}
print(data)
sem.signal()
}
// Code hangs here waiting for completion block to get called, but it never does when OperationQueue is main
let _ = sem.wait(timeout: .distantFuture)
}
do {
try main()
} catch (let error) {
print("ERROR: \(error)")
}
When I use a basic URLSession object the request completes fine. However, if I attempt to pass in my own URLSessionTaskDelegate to print the bytesSent, the call never happens. Furthermore, if I set my delegateQueue
to OperationQueue.main
, the request itself never completes.
I'm sure there's some kind of concurrency issue here, but I have no idea where to start debugging this. Any help is appreciated!