Swift возвращает данные из URLSession
Я не могу вернуть данные из своего 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. На данный момент я невежественен...
4 ответа
Вы можете использовать этот метод завершения блока для отправки окончательного ответа:
Для экземпляра: Я возвратил строку в блоке завершения, после успешного ответа без ошибок просто передам результат в блок.
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
}
Это решит ваше следующее требование.
{
(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()
строка, а затем метод заканчивается. В этот момент, потому что ваш метод определен как возвращающий String
нужно вернуть String
, Возвращать его из обработчика завершения не годится, потому что это еще не было выполнено, это будет выполнено позже.
Есть много разных способов справиться с асинхронным программированием, но один из способов справиться с этим - изменить createRequest()
метод, так что он не определен, чтобы вернуть String
создать метод, который принимает String
в качестве параметра, который делает то, что вы хотели сделать с возвращаемым значением, а затем вызвать этот метод из вашего обработчика завершения.
Просто в вашем вызове функции
var webString = try String(contentsOf: URL(string: url)!)
И у вас есть полный ответ в строке, что вы можете вернуть
Вместо использования return попробуйте использовать обработчики завершения, как вы упоминали в своем вопросе.
func createRequest(qMes: message, location: String, method: String, completionHandler: @escaping (_ data:Data?, _ response: URLResponse?, _ error: NSError?) -> Void)
Тогда вместо return
вы должны использовать что-то вроде completionHandler(data, response, error)
И вот как вы делаете запрос:
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()