У меня есть функция, которая обеспечивает слой поверх URLSession.Когда эта функция вызывается, я хотел бы проверить, не истек ли текущий токен доступа, если он истек, если бы он имел, я бы приостановил текущий вызов, сделал вызов, чтобы запросить новый токен, заменил существующую запись в связке ключей, затем продолжил свызов.
func profile(with endpoint: ProfilesEndpoint, method: HTTPMethod, body: String?, headers: [String: String]?, useAuthToken: Bool = true, completion: @escaping (Either<ProfileResponse>) -> Void) {
var request = endpoint.request
request.httpMethod = method.rawValue
if let body = body {
request.httpBody = body.data(using: .utf8)
}
if useAuthToken {
if !AuthService.shared.isTokenValid {
let group = DispatchGroup()
group.enter()
OAuthService.shared.requestRefreshToken()
group.leave()
}
let (header, token) = AuthService.shared.createAuthHeaderForNetworkRequest()
request.addValue(token, forHTTPHeaderField: header)
}
if let headers = headers {
for (key, value) in headers {
request.addValue(value, forHTTPHeaderField: key)
}
}
execute(with: request, completion: completion)
}
Существует механизм для работы с цепочкой для ключей, поэтому, пожалуйста, предположите, что он на месте.
Функция для запроса нового токена выглядит как
func requestRefreshToken() -> Void {
if let refreshToken = KeychainWrapper.standard.string(forKey: "RefreshToken") {
var postBody = "grant_type=\(refreshTokenGrantType)&"
postBody += "client_id=\(clientId)&"
postBody += "refresh_token=\(refreshToken)&"
let additionalHeaders = [
"Content-Type": "application/x-www-form-urlencoded;"
]
APIClient.shared.identity(with: .token, method: .post, body: postBody, headers: additionalHeaders, useAuthToken: false) { either in
switch either {
case .success(let results):
guard let accessToken = results.accessToken, let refreshToken = results.refreshToken else { return }
AuthService.shared.addTokensToKeyChain(tokens: ["AccessToken": accessToken, "RefreshToken": refreshToken])
case .error(let error):
print("Error:", error)
}
}
}
}
Я ожидал, что выполнение приостановится здесь
group.enter()
OAuthService.shared.requestRefreshToken()
group.leave()
Однако это не так.
Как можно дождаться завершения этого вызова перед завершением остальной части функции?