Swift 3 - 发送make同步http请求
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift 3 - 发送make同步http请求相关的知识,希望对你有一定的参考价值。
我有以下代码:
func completeLoadAction(urlString:String) -> Int {
let url = URL(string:urlString.trimmingCharacters(in: .whitespaces))
let request = URLRequest(url: url!)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=(error)")
let ac = UIAlertController(title: "Unable to complete", message: "The load has been added to the completion queue. This will be processed once there is a connection.", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
self.present(ac, animated: true)
return
}
let httpStatus = response as? HTTPURLResponse
var httpStatusCode:Int = (httpStatus?.statusCode)!
let responseString = String(data: data, encoding: .utf8)
print("responseString = (responseString)")
let ac = UIAlertController(title: "Completed Successfully", message: "The "+coldel+" has been completed successfully", preferredStyle: .alert)
ac.addAction(UIAlertAction(title:"Continue", style: .default, handler: { action in self.performSegue(withIdentifier: "segueConfirmedLoad", sender: self) }))
self.present(ac, animated: true)
}
task.resume()
return httpStatusCode
}
我需要能够调用它并同时检查返回值,因为它是http状态代码,它会让我知道调用是否成功。
问题是因为它在dataTask中我无法访问响应状态代码
var httpStatusCode:Int = (httpStatus?.statusCode)!
因为任务在调用Task.Resume()之前不会启动,并且任务是异步的,所以它永远不会工作。
这有什么办法吗?
答案
总有一种方法可以使用异步模式。
要使函数异步,请添加完成块
func completeLoadAction(urlString:String, completion: (Int) -> ()) {
let url = URL(string:urlString.trimmingCharacters(in: .whitespaces))
let request = URLRequest(url: url!)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=(error)")
DispatchQueue.main.async {
let ac = UIAlertController(title: "Unable to complete", message: "The load has been added to the completion queue. This will be processed once there is a connection.", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
self.present(ac, animated: true)
}
completion(0) // or return an error code
return
}
let httpStatus = response as? HTTPURLResponse
var httpStatusCode:Int = (httpStatus?.statusCode)!
let responseString = String(data: data, encoding: .utf8)
print("responseString = (responseString)")
DispatchQueue.main.async {
let ac = UIAlertController(title: "Completed Successfully", message: "The "+coldel+" has been completed successfully", preferredStyle: .alert)
ac.addAction(UIAlertAction(title:"Continue", style: .default, handler: { action in self.performSegue(withIdentifier: "segueConfirmedLoad", sender: self) }))
self.present(ac, animated: true)
}
completion(httpStatusCode)
}
task.resume()
}
并且这样称呼它
completeLoadAction(urlString: "www.something.com") { code in
print(code)
}
另一答案
要使它同步并等待,您可以使用下面的信号量
struct Login {
static func execute() -> Bool {
let request = NSURLRequest....
var success = false
let semaphore = DispatchSemaphore(value: 0)
let task = URLSession.shared.dataTask(with: request, completionHandler: { _, response, error in
if let error = error {
print("Error while trying to re-authenticate the user: (error)")
} else if let response = response as? HTTPURLResponse,
300..<600 ~= response.statusCode {
print("Error while trying to re-authenticate the user, statusCode: (response.statusCode)")
} else {
success = true
}
semaphore.signal()
})
task.resume()
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
return success
}
}
另一答案
这不适用于所有情况。假设您正在实现共享扩展。并且你要覆盖返回布尔值的isContentValid()
方法(如果内容有效,则为true)...但是为了测试内容是否有效,您需要验证服务器是否正在运行(这是一个人为的例子)。如果你进行异步http调用 - 完成块或不 - 你不能返回boolean的正确值;实现此目的的唯一方法是执行同步调用并根据返回值返回true / false。
发布信号量模式的答案是在这种情况下使用的正确答案。
以上是关于Swift 3 - 发送make同步http请求的主要内容,如果未能解决你的问题,请参考以下文章
我可以在 Swift 中通过 NSURLSession 以某种方式执行同步 HTTP 请求吗
swift 使用基本HTTP authirization发送请求