I made a synchron function to sign in a user, but the http request inside the function is asyc, so the parent function returns false before the async part happens. I know that I somehow have to turn signingInExtension
an async function with completion handling, and then call it differently from the viewDidLoad function, I just cannot figure out the syntax.
Also the http request comes with a completionHandler, but I do not understand how I can modify it to pass its return value up to where it is called.
override func viewDidLoad() {
signedIn = signingInExtension()
}
func signingInExtension() -> Bool {
if (self.singleUseIdentityToken != nil) {
if (!tokenExpired(t: self.singleUseIdentityToken)) {
let parameters = [
"method": "single-use-identity-token",
"token": self.singleUseIdentityToken!
] as [String : Any]
let url = URL(string: self.endpoint + "/auth/signin")!
let session = URLSession.shared
var request = URLRequest(url: url)
request.httpMethod = "POST"
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil else {
return
}
guard let data = data else {
return
}
do {
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
if (json["token"] == nil) {
return
} else {
print(json["token"] as! String)
// store token in file
// here I would like signingInExtension to return true
// but it already returned false because I am not handling async correctly
}
}
} catch let error {
print(error.localizedDescription)
}
})
task.resume()
}
}
return false // this happens before task
}
How can I from within the http tasks completion handler return either true
or false
all the way out to where I call signingInExtension ?