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 答案来证明这一点。)
我正在使用 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 答案来证明这一点。)