我正在用Alamofire实现RequestRetrier,以刷新给定用户的accessToken。
func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {
lock.lock() ; defer { lock.unlock() }
if let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401 {
requestsToRetry.append(completion)
if !isRefreshing {
refreshToken(completion: { [weak self] succeded, accessToken in
guard let strongSelf = self else { return }
strongSelf.lock.lock() ; defer { strongSelf.lock.unlock() }
strongSelf.requestsToRetry.forEach{ $0(succeded, 0.0) }
strongSelf.requestsToRetry.removeAll()
})
}
} else {
completion(false, 0.0)
}
}
调用strongSelf.lock.lock() ; defer { strongSelf.lock.unlock() }
时,它不会继续执行,因此我遇到了无限循环。我尝试检查strongSelf.lock.try()
的结果并返回false。
这是当我使用错误的密码登录时发生的,因此服务器返回了401。
这是我的refreshToken代码
guard !isRefreshing else { return }
// ... Get user ... //
if let user = user {
isRefreshing = true
signIn(user: userDTO)
.subscribe(onNext: { [weak self] userSession in
guard let strongSelf = self else { return }
// ... Save accessToken ... //
completion(true, userSession.accessToken)
strongSelf.isRefreshing = false
}, onError: { [weak self] error in
guard let strongSelf = self else { return }
// ... Log out user ... //
completion(false, nil)
strongSelf.isRefreshing = false
})
.disposed(by: bag)
} else {
completion(false, nil)
}
答案 0 :(得分:1)
如Github问题https://github.com/Alamofire/Alamofire/issues/2544所示,我可以通过以下方法解决此问题:
workflow Test
{
$SubscriptionName = Get-AutomationVariable -Name 'VAR-AUTO-SubscriptionName'
$SubscriptionName
$AzureAutomationCredential = Get-AutomationPSCredential -Name 'CRE-AUTO-AutomationUser'
$AzureAutomationCredential
}
到
private let lock = NSLock()
它们之间的区别在于,如果同一线程尝试锁定,则可以解锁递归锁定。