Home > Software design >  Swift - Async/Await not stopping to let task finish
Swift - Async/Await not stopping to let task finish

Time:02-25

I'm writing a simple program designed to talk to a server, get some information, and display it. However, I'm running into issues with the async code, mainly that the code isn't stopping to allow the server to respond before continuing.

I know I have to be doing something wrong but have no idea what, any help is appreciated.

override func viewDidLoad() {
    super.viewDidLoad()
    Task{
        let accessToken = await getToken()
    }
    print("Done")
}

private func getToken() async -> String{
    let url = URL(string: "https://api.petfinder.com/v2/oauth2/token")
    let payload = "grant_type=client_credentials&client_id=GUQj1MdQN3QunoxXz4vdd0DHPlcJC6yuqCLCEXavriJ4W6wTYV&client_secret=7whgSG3ZX6m9Cwfr2vEakOH90fSn3g0isIlae0CC".data(using: .utf8)
    var request = URLRequest(url: url!)
    request.httpMethod = "POST"
    request.httpBody = payload

    do{
        let (data,_) = try await URLSession.shared.data(for: request)
        let APItoken: token = try! JSONDecoder().decode(token.self, from: data)
        return APItoken.access_token
    }
    catch{
        return ""
    }
}

CodePudding user response:

If I understood the problem, you see "Done" being printed before the getToken() method is completed, right?

The problem is that print("Done") is outside of the Task.

When you call Task, it starts running what's in the closure and it immediately resumes after the closure, while your task is running in the background.

Place your print() inside the Task closure, right after the getToken() method, and you'll see that it'll be "Done" after you complete your POST request.

    Task{
        let accessToken = await getToken()
        print("Done")
    }

CodePudding user response:

Await does not completely block your code, instead the thread that makes the call can be used to do something else, like get more user input, execute other task content that was waiting for a result and now has it. think like closure call backs, everything after the await, will be executed later, probable up to the enclosing task. Print(“done”) is not in your task, so it’s not required to wait for the code in the task execute, the task content is probable executing in another thread, as it doesn’t contain code that has to execute in the main thread.

  • Related