Swift 程序从不进入 dataTask 的 CompletionHandler

Swift program never enters CompletionHandler for a dataTask

我正在使用 Swift 实现 REST API。当然,这 API 的一部分是使用 HTTP 请求来检索和发送数据。

完全公开,我对 Swift 没有经验,可以这么说,我正在将其作为一个学习项目来弄湿我的脚。但它变成了一个比我预期的更困难的项目。

在实现第一个get方法时,我(终于)摆脱了所有的编译错误。但是,当我调用使用 URLRequest、URLSession、dataTask 等的函数时,它永远不会被输入。

在调试程序时,我可以看到程序执行到达 CompletionHandler,然后直接跳过 "task.resume()."

在 Swift Playground 中可以进行类似的构建,但在实际项目中并不适用。

到目前为止我已经尝试了一些事情,即让函数访问一个 class 实例变量,希望这会强制它执行。但事实并非如此。

我认为问题可能与处理同步性有关,也许我需要使用信号量,但我想首先确保我没有遗漏任何明显的东西。

import Foundation
/**
 A class to wrap all GET and POST requests, to avoid the necessity of repeatedly writing request code in each API method.
 */
class BasicRequest {
    private var url: URL
    private var header: [String: String]
    private var responseType: String

    private var jsonResponse: Any?


    init(url: URL, header: [String: String], responseType: String) {
        self.url = url
        self.header = header
        self.responseType = responseType
    } //END INIT

    public func requestJSON() -> Any {
        // Create the URLRequest object, and fill the header with the header fields as provided.
        var urlRequest = URLRequest(url: self.url)
        for (value, key) in self.header {
            urlRequest.addValue(value, forHTTPHeaderField: key)
        }

        let task = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
            print("Entered the completion handler")
            if error != nil {
                return
            }
            guard let httpResponse = response as? HTTPURLResponse, 200 == httpResponse.statusCode else {
                print("HTTP Request unsuccessful")
                return
            }
            guard let mime = response?.mimeType, mime == "application/json" else {
                print("Not a JSON response")
                return
            }
            do {
                let json = try JSONSerialization.jsonObject(with: data!, options: [])
                print(json)
                self.jsonResponse = json
            } catch {
                print("Could not transform to JSON")
                return
            }
        }
        task.resume()

        return "Function has returned"
    } //END REQUESTJSON
}

预期的结果将返回一个 JSON 对象,但事实似乎并非如此。

关于错误消息,我得到 none。我在调试器中获得的唯一日志是样板 "process exited with code 0."

说实话,我不知道是什么导致它不起作用。

您似乎是在 command-line 应用程序中编写此内容。在这种情况下,程序会在 URLRequest 完成之前终止。

I think the issue may be dealing with synchronicity, and perhaps I need to use a Semaphore, but I want to make sure I'm not missing anything obvious first.

完全正确。

Swift中的典型工具是DispatchGroup,它只是一种higher-level信号量。在开始请求之前调用 dispatchGroup.enter(),在完成处理程序结束时调用所有 dispatchGroup.leave()。在您的调用代码中,包含 dispatchGroup.wait() 以等待它。 (如果不清楚,我可以为其添加代码,但您也可以找到很多 SO 答案来证明这一点。)