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 从未在命令行工具中调用[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何避免“从未使用方法”消息?

为啥我的条件从未满足? [复制]

onIabPurchaseFinished 从未调用过。

Nuxt 常量被赋值但从未使用过

但愿从未有过我

为啥我的 UIViewController 初始化程序从未被调用?