Swift return 来自 URLSession 的数据
Swift return data from URLSession
我无法 return 来自我的 HTTP 请求的数据,我也无法让完成处理程序工作。所以请帮助我解决这个问题:
public static func createRequest(qMes: message, location: String, method: String) -> String{
let requestURL = URL(string: location)
var request = URLRequest(url: requestURL!)
request.httpMethod = method
request.httpBody = qMes.toString().data(using: .utf8)
let requestTask = URLSession.shared.dataTask(with: request) {
(data: Data?, response: URLResponse?, error: Error?) in
if(error != nil) {
print("Error: \(error)")
}
return String(data: data!, encoding: String.Encoding.utf8) as String!
}
requestTask.resume()
}
在 void 函数中期待非 void return 语句。到这里我就一头雾水了...
{
(data: Data?, response: URLResponse?, error: Error?) in
if(error != nil) {
print("Error: \(error)")
}
return String(data: data!, encoding: String.Encoding.utf8) as String!
}
这部分代码是 dataTask()
方法的完成处理程序。它是您传递给 dataTask()
方法的代码块,稍后将执行(当服务器发回一些数据或出现错误时)。并没有立即执行。
这意味着当您上面的 createRequest()
方法正在执行时,它直接通过该代码,然后进入 requestTask.resume()
行,然后该方法结束。那时,因为您的方法被定义为 returning a String
,您需要 return a String
。从完成处理程序返回它是不好的,因为它还没有被执行,稍后将被执行。
有很多不同的方法来处理异步编程,但解决这个问题的一种方法是更改您的 createRequest()
方法,使其不被定义为 return 和 String
,创建一个将 String
作为参数的方法,该方法可以对 return 值执行您想做的任何事情,然后从完成处理程序中调用该方法。
不要使用 return,而是尝试使用您在问题中提到的完成处理程序。
func createRequest(qMes: message, location: String, method: String, completionHandler: @escaping (_ data:Data?, _ response: URLResponse?, _ error: NSError?) -> Void)
那么你应该使用 completionHandler(data, response, error)
而不是 return
这就是您提出请求的方式:
var request = URLRequest(url: Foundation.URL(string: URL)!)
request.httpMethod = method
//request.addValue(authString, forHTTPHeaderField: "Authorization") // if you need some
let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
guard error == nil && data != nil else
{
print("error=\(error)")
completionHandler(data, response, error as NSError?)
return
}
completionHandler(data, response, error as NSError?)
})
task.resume()
您可以使用此完成块方法发送最终响应:
例如:
我在完成块中返回了字符串,成功响应后没有错误,只需将结果传递到块中。
public func createRequest(qMes: String, location: String, method: String , completionBlock: @escaping (String) -> Void) -> Void
{
let requestURL = URL(string: location)
var request = URLRequest(url: requestURL!)
request.httpMethod = method
request.httpBody = qMes.data(using: .utf8)
let requestTask = URLSession.shared.dataTask(with: request) {
(data: Data?, response: URLResponse?, error: Error?) in
if(error != nil) {
print("Error: \(error)")
}else
{
let outputStr = String(data: data!, encoding: String.Encoding.utf8) as String!
//send this block to required place
completionBlock(outputStr!);
}
}
requestTask.resume()
}
您可以使用下面的代码来执行上面的完成块功能:
self.createRequest(qMes: "", location: "", method: "") { (output) in
}
这将解决您的以下需求。
就在你的函数调用中
var webString = try String(contentsOf: URL(string: url)!)
而且你有完整的字符串回复,你可以 return
我无法 return 来自我的 HTTP 请求的数据,我也无法让完成处理程序工作。所以请帮助我解决这个问题:
public static func createRequest(qMes: message, location: String, method: String) -> String{
let requestURL = URL(string: location)
var request = URLRequest(url: requestURL!)
request.httpMethod = method
request.httpBody = qMes.toString().data(using: .utf8)
let requestTask = URLSession.shared.dataTask(with: request) {
(data: Data?, response: URLResponse?, error: Error?) in
if(error != nil) {
print("Error: \(error)")
}
return String(data: data!, encoding: String.Encoding.utf8) as String!
}
requestTask.resume()
}
在 void 函数中期待非 void return 语句。到这里我就一头雾水了...
{
(data: Data?, response: URLResponse?, error: Error?) in
if(error != nil) {
print("Error: \(error)")
}
return String(data: data!, encoding: String.Encoding.utf8) as String!
}
这部分代码是 dataTask()
方法的完成处理程序。它是您传递给 dataTask()
方法的代码块,稍后将执行(当服务器发回一些数据或出现错误时)。并没有立即执行。
这意味着当您上面的 createRequest()
方法正在执行时,它直接通过该代码,然后进入 requestTask.resume()
行,然后该方法结束。那时,因为您的方法被定义为 returning a String
,您需要 return a String
。从完成处理程序返回它是不好的,因为它还没有被执行,稍后将被执行。
有很多不同的方法来处理异步编程,但解决这个问题的一种方法是更改您的 createRequest()
方法,使其不被定义为 return 和 String
,创建一个将 String
作为参数的方法,该方法可以对 return 值执行您想做的任何事情,然后从完成处理程序中调用该方法。
不要使用 return,而是尝试使用您在问题中提到的完成处理程序。
func createRequest(qMes: message, location: String, method: String, completionHandler: @escaping (_ data:Data?, _ response: URLResponse?, _ error: NSError?) -> Void)
那么你应该使用 completionHandler(data, response, error)
return
这就是您提出请求的方式:
var request = URLRequest(url: Foundation.URL(string: URL)!)
request.httpMethod = method
//request.addValue(authString, forHTTPHeaderField: "Authorization") // if you need some
let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
guard error == nil && data != nil else
{
print("error=\(error)")
completionHandler(data, response, error as NSError?)
return
}
completionHandler(data, response, error as NSError?)
})
task.resume()
您可以使用此完成块方法发送最终响应:
例如: 我在完成块中返回了字符串,成功响应后没有错误,只需将结果传递到块中。
public func createRequest(qMes: String, location: String, method: String , completionBlock: @escaping (String) -> Void) -> Void
{
let requestURL = URL(string: location)
var request = URLRequest(url: requestURL!)
request.httpMethod = method
request.httpBody = qMes.data(using: .utf8)
let requestTask = URLSession.shared.dataTask(with: request) {
(data: Data?, response: URLResponse?, error: Error?) in
if(error != nil) {
print("Error: \(error)")
}else
{
let outputStr = String(data: data!, encoding: String.Encoding.utf8) as String!
//send this block to required place
completionBlock(outputStr!);
}
}
requestTask.resume()
}
您可以使用下面的代码来执行上面的完成块功能:
self.createRequest(qMes: "", location: "", method: "") { (output) in
}
这将解决您的以下需求。
就在你的函数调用中
var webString = try String(contentsOf: URL(string: url)!)
而且你有完整的字符串回复,你可以 return