Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return String from URLSession Completion Handler function Swift 3

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!

like image 400
m00912 Avatar asked Nov 25 '25 07:11

m00912


1 Answers

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")
    }
}
like image 198
Brandon A Avatar answered Nov 27 '25 00:11

Brandon A



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!