How to pause another async call if one of them catch a condition that need to be done first before continuing the other calls? From the code below (simplified), when makeRequest got 401, then it should call refreshSession and pause other calls until this one is finished.
let refreshSessionDispatchQueue = DispatchQueue(label: "refreshSession")
var refreshSessionJobQueue: [APIRequest] = []
// This function will be called by each of APIs that got 401 error code
private func refreshSession(errorCode: String? = nil, request: APIRequest) {
refreshSessionDispatchQueue.async {
self.refreshSessionJobQueue.append(request)
}
// The idea is, after all job appended to the jobQueue, let says after 1', it will call another function to execute another job
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
self.executeRefreshSessionJobQueue()
}
}
// This is to execute refreshSession, and if it's succeed, all job on the jobQueue will be re-executed
private func executeRefreshSessionJobQueue() {
DispatchQueue.main.async {
let readyToRefreshSessionJobQueue = self.refreshSessionJobQueue
if self.refreshSessionJobQueue.count > 0 {
self.refreshSessionJobQueue = []
self.refreshSession { [weak self] succeed in
if succeed {
for job in readyToRefreshSessionJobQueue {
self?.makeRequest(baseURL: job.baseURL, endpoint: job.endpoint, method: job.method, encoding: job.encoding, headers: job.headers, params: job.params, customBody: job.customBody, completion: job.completion)
}
self?.refreshSessionJobQueue = []
} else {
// And if it's failed, all the job should be removed and redirect the page to the login page
self?.refreshSessionJobQueue = []
ErrorHandler.relogin()
}
}
}
}
}
If you need to retry the API when getting 401, you can try using RequestRetrier from Alamofire’s RequestInterceptor. It basically retries a request that encountered an error such as 401 in your case.
Full example of implementation can be found here. Hope it helps, cheers!