I need this function (which is getting some data from a database) to return a string but I'm having trouble figuring out how. I've found some similar questions/solutions but I'm still struggling to implement a proper solution (I'm pretty new with 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
}
}
Thanks!
Your session.dataTask(with: method is asynchronous. This means that it is going to execute "in the background" and with inform you of when it is finished getting a response from it's call. It will inform you of this inside your block below the session.dataTask(with: portion inside the "{}". As if appears, you are doing some processing with the JSON that you receive and formatting that into the string you'd like to return from this function. BUT you are called return string at the bottom well before your call is getting completed, so you will return "" nothing. What you really need to do is not return anything from your function, but instead use a completion block:
1) Declare this atop your file:
typealias StringCompletion = (_ success: Bool, _ string: String) -> Void
2) Modify your function to take a parameter for your completion
// This
static func pReq(jsonURL : String, col : String) -> String
// Becomes This
static func pReq(jsonURL : String, col : String, completion: @escaping StringCompletion)
3) Inside your function call your completion and pass back a Bool to indicate it was a successful call and pass back the string as well
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) Usage:
Helper().pReq(jsonURL: jsonURL, col: col) { (success, string) in
if success {
print("Success: \(string)")
}
else {
print("Failure: Unable To Get String")
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With