Возвращаемая строка из функции обработчика завершения URLSession Swift 3
Мне нужна эта функция (которая получает некоторые данные из базы данных), чтобы вернуть строку, но у меня возникают проблемы с выяснением, как. Я нашел несколько похожих вопросов / решений, но я все еще пытаюсь найти правильное решение (я довольно новичок в Swift)
class Helper{
static func pReq(jsonURL : String, col : String) -> String {
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let url = URL(string: jsonURL)!
let request = URLRequest(url: url)
var string = ""
let downloadTask = session.dataTask(with: request, completionHandler: {(data, response, error) in
if(error == nil){
print("data = \(String(describing: data))")
do{
print(jsonURL)
let dataDownloadedAsJson = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:AnyObject]
print("dataDownloadedAsJson = \(dataDownloadedAsJson)")
do{
if(dataDownloadedAsJson[col] as? String != nil){
string = (dataDownloadedAsJson[col] as? String)!
}
}
}
catch{
}
}
else{
print("Error downloading data. Error = \(String(describing: error))")
}
})
downloadTask.resume()
return string
}
}
Спасибо!
1 ответ
Ваш session.dataTask(with:
Метод асинхронный. Это означает, что он будет выполняться "в фоновом режиме" и сообщать вам, когда он закончил, получая ответ от своего вызова. Он проинформирует вас об этом внутри вашего блока под session.dataTask(with:
часть внутри "{}
Msgstr "Как будто появляется, вы выполняете некоторую обработку с помощью полученного вами JSON и форматируете его в строку, которую хотите вернуть из этой функции. НО вас вызывают return string
внизу задолго до того, как ваш звонок будет завершен, поэтому вы вернетесь ""
ничего такого. Что вам действительно нужно сделать, это не возвращать что-либо из вашей функции, а вместо этого использовать блок завершения:
1) Объявите это поверх вашего файла:
typealias StringCompletion = (_ success: Bool, _ string: String) -> Void
2) Измените вашу функцию, чтобы получить параметр для вашего завершения
// This
static func pReq(jsonURL : String, col : String) -> String
// Becomes This
static func pReq(jsonURL : String, col : String, completion: @escaping StringCompletion)
3) Внутри вашей функции вызовите ваше завершение и передайте обратно Bool
указать, что это был успешный вызов и передать обратно string
также
class Helper{
static func pReq(jsonURL : String, col : String, completion: @escaping StringCompletion) {
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let url = URL(string: jsonURL)!
let request = URLRequest(url: url)
var string = ""
let downloadTask = session.dataTask(with: request, completionHandler: {(data, response, error) in
if(error == nil){
print("data = \(String(describing: data))")
do{
print(jsonURL)
let dataDownloadedAsJson = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:AnyObject]
print("dataDownloadedAsJson = \(dataDownloadedAsJson)")
do{
if(dataDownloadedAsJson[col] as? String != nil){
string = (dataDownloadedAsJson[col] as? String)!
completion(true, string)
}
}
catch { completion(false, string) }
}
catch{
completion(false, string)
}
}
else{
print("Error downloading data. Error = \(String(describing: error))")
completion(false, string)
}
})
downloadTask.resume()
}
}
4) Использование:
Helper().pReq(jsonURL: jsonURL, col: col) { (success, string) in
if success {
print("Success: \(string)")
}
else {
print("Failure: Unable To Get String")
}
}