0

I am trying to write a function that will return the value from an if statement. The function looks like this:

func getJson() -> String {
    if let url = URL(string: "https://api.snow.quirky.codes/cardrona") {
       URLSession.shared.dataTask(with: url) { data, response, error in
        if let data = data {
            let jsonDecoder = JSONDecoder()
                do {
                    let parsedJSON = try jsonDecoder.decode(Welcome.self, from: data)
                    for temp in parsedJSON.todaysTemp {
                        if let mid = temp.mid1640M {
                            return mid
                            //Causes "unexpected non-void return value in void function" error
                            }
                        }
                    } catch {
                        print(error)
                    }
               }
       }.resume()
    }
}

I have tried setting a global variable and setting it to mid inside the if statement but then when I go to print it outside the function it just prints "\n".

Ajay Quirk
  • 23
  • 3
  • 2
    [This](https://stackoverflow.com/questions/25203556/returning-data-from-async-call-in-swift-function) should answer your question. – Sweeper Jul 16 '20 at 01:39

1 Answers1

-1

There are 2 problems :

  • the completion handler is a non void function so you can not return anything from it. You just can save the string in some global variable.`
  • the task execute in background, that means that when the instruction URLSession.shared.dataTask(...).resume() finish its execution, that means only the background task has started and that is why you can not see anything with the print. The getJson() function start a data downloading but does not wait the end of it. The data task is asynchronous and its completion handler will execute later (may take seconds if network is not good)

You use a semaphore to handle this :

  • you can add at the beginning of the getJson() function :

    var receivedMid : String = ""
    let semaphore = DispatchSemaphore(value: 0)

  • Inside the data task :
    receivedMid = mid

  • then before the end of the completion handler add :
    semaphore.signal()

  • then after resume() :
    semaphore.wait()
    return receivedMid

Ptit Xav
  • 3,006
  • 2
  • 6
  • 15