I have a simple task with threads, but what seems to help everyone else, doesn’t work for me and I don’t understand why.
This is my button processing:
AnyButton(action: {
if isPhoneMode {
print("starting long running tasks")
let group = DispatchGroup()
group.enter()
DispatchQueue.global().async {
urlService.loginRequest(login: "+\(countryCode)\(phoneNumber)", password: password, completion: {
print("print in complition")
})
print("long task done!")
group.leave()
}
group.notify(queue: DispatchQueue.global()) {
print("all tasks done!")
}
}
This is loginRequest
:
func loginRequest(login: String, password: String, completion: @escaping () -> Void) {
let parameters: Parameters = [
"language": "EN",
"password": password,
"username": login
]
let url = "someURL"
let authRequest = AF.request(url,
method: .post,
parameters: parameters,
encoding: JSONEncoding.default)
authRequest.responseString { response in
switch response.result {
case .success(let value):
let responseArr = value.components(separatedBy: "\u{0022}")
if responseArr[11] == "ACTIVE" {
self.loginStatus = .correctLogin
print("correct login!")
}
case .failure(let error):
print("Error: \(String(describing: error))")
self.loginStatus = .requestFail
}
}
completion()
}
group.notify
can't track correctly my request. Correct login always last in console: Why so?
starting long running tasks
print in complition
long task done!
all tasks done!
correct login!
I want it to be before “long task done”. How can i do this?
You ask:
“Correct login” always last in console: Why so?
Because your call to your completion handler is not in the right place. E.g.
func loginRequest(login: String, password: String, completion: @escaping () -> Void) {
…
authRequest.responseString { response in
switch response.result { … }
completion() // Move `completion` here
}
// completion() // It should not be here
}
You have a similar problem in your dispatch group, namely that leave
belongs inside the completion handler:
AnyButton(action: {
if isPhoneMode {
print("starting long running tasks")
let group = DispatchGroup()
group.enter()
urlService.loginRequest(login: "+\(countryCode)\(phoneNumber)", password: password) {
print("print in completion")
group.leave() // Move `leave` here
}
print("long task done!")
// group.leave() // not here
group.notify(queue: DispatchQueue.global()) {
print("all tasks done!")
}
}
})
Note, I’ve removed the redundant dispatch to the global queue (as loginRequest
already runs asynchronously).
But since you have a single task, the dispatch group is redundant, too. You only use groups if you have multiple tasks for which you need to be notified when they are complete. In this case, though, it is syntactic noise. So, this can be simplified further, to:
AnyButton(action: {
if isPhoneMode {
print("starting long running tasks")
urlService.loginRequest(login: "+\(countryCode)\(phoneNumber)", password: password) {
print("print in completion")
}
}
})