URLSessionTaskDelegate 从未在命令行工具中调用[重复]
Posted
技术标签:
【中文标题】URLSessionTaskDelegate 从未在命令行工具中调用[重复]【英文标题】:URLSessionTaskDelegate never called in Command Line tool [duplicate] 【发布时间】:2020-08-04 18:21:22 【问题描述】:我正在尝试编写我的第一个 Swift 命令行工具。该工具创建一个网络请求,我想使用 URLSessionTaskDelegate 打印请求的进度。
基本的 URL 请求代码在这里:
编辑:更新更完整的示例
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)")
当我使用基本的 URLSession 对象时,请求可以正常完成。但是,如果我尝试传入我自己的 URLSessionTaskDelegate 来打印 bytesSent,则调用永远不会发生。此外,如果我将delegateQueue
设置为OperationQueue.main
,则请求本身永远不会完成。
我确定这里存在某种并发问题,但我不知道从哪里开始调试它。任何帮助表示赞赏!
【问题讨论】:
【参考方案1】:您的 CLI 应用是否定义了 RunLoop?如果没有 RunLoop,它将退出,并且当您的 main 退出时,所有挂起的任务都会被释放。尝试添加类似:
while RunLoop.main.run(mode: .default, before: .distantFuture)
在主文件的末尾。
【讨论】:
它没有,但不幸的是,这个问题似乎与退出无关。代码在信号量等待时挂起,因为从不调用请求完成块 - 但当委托/OperationQueue 不存在时,它会被正常调用。 我没有注意到信号量,它看起来阻塞了主线程,这会阻止delegateQueue回调它。如果把delegateQueue改成nil,会收到回调吗?以上是关于URLSessionTaskDelegate 从未在命令行工具中调用[重复]的主要内容,如果未能解决你的问题,请参考以下文章