I have a closure to retrieve a token string:
var getAccessToken = { () -> (String) in
var token = String("")
credentialsManager.credentials(minTTL: 60) { result in
switch result {
case .success(let credentials):
token = credentials.accessToken
case .failure(let error):
token = ""
}
}
return token
}
When I call getAccessToken()
from another function like below, it always returns empty, as it doesn’t wait for credentialsManager.credentials
closure to return:
func getUserProfile(completion: @escaping (UserProfile) -> ()) {
let accessToken = getAccessToken()
let url = URL(string: "https://asdf.com")!
enum DataTaskError: Error {
case invalidResponse, rateLimited, serverBusy
}
var request = URLRequest(url: url)
request.addValue("Bearer (accessToken)", forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
URLSession.shared.dataTask(with: request) { (data, _, _) in
guard let data = data else { return }
do {
let userProfile = try JSONDecoder().decode(UserProfile.self, from: data)
DispatchQueue.main.async {
completion(userProfile)
}
} catch {
print(error.localizedDescription)
}
}
.resume()
}
I tried using a completion handler with getAccessToken
:
func getAccessToken(completion: @escaping () -> (String)) {
//...
completion(token)
}
but Swift errored: Argument passed to call that takes no arguments
2
Answers
You are not using
DataTaskError
in your function. Given that, there is no reason to use ado/catch
.You return the token before the credentialsManager.credentials generate the token in the first case. Second case your completion handler syntax is wrong for this scenario. Use the proper completion handler as below.