Ios 具有超时错误处理的Alamofire RequestRetrier
我正在使用Ios 具有超时错误处理的Alamofire RequestRetrier,ios,swift,error-handling,alamofire,Ios,Swift,Error Handling,Alamofire,我正在使用RequestRetrier自动续订API的访问令牌。但在每个请求函数中,我都希望捕获超时错误,但是中的case(let error)。responseJSONbody从不执行,因为(我猜)我将检索器添加到我的accessSessionManager。下面是它的样子: lazy var accessSessionManager: SessionManager = { let configuration = URLSessionConfiguration.default
RequestRetrier
自动续订API的访问令牌。但在每个请求函数中,我都希望捕获超时错误,但是中的case(let error)
。responseJSON
body从不执行,因为(我猜)我将检索器添加到我的accessSessionManager
。下面是它的样子:
lazy var accessSessionManager: SessionManager = {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = Configuration.timeout
configuration.timeoutIntervalForResource = Configuration.timeout
let sessionManager = Alamofire.SessionManager(configuration: configuration)
let oAuth2Handler = OAuth2Handler()
sessionManager.retrier = oAuth2Handler
sessionManager.adapter = oAuth2Handler
return sessionManager
}()
func changeName(newName: String,completionHandler: ((_ success: Bool, _ error: String?) -> ())?) {
guard let accessToken = self.getAccessToken() else { return }
let parameters = ["access_token": accessToken, "name": newName] as [String : Any]
self.accessSessionManager.request(Constants.nameUrl, method: .get, parameters: parameters).responseJSON { response in
switch response.result {
case .success(let json):
let jsonDict = JSON(json)
if let success = jsonDict["success"].bool {
completionHandler?(success, nil)
}
case .failure(let error):
if error._code == NSURLErrorTimedOut {
completionHandler?(false, "Please check your Internet connection and try again!")
} else if response.response?.statusCode == 400 {
completionHandler?(false, "Sorry, name not found")
} else if response.response?.statusCode != 401 {
completionHandler?(false, error.localizedDescription)
}
}
}
}
}
....
....
class OAuth2Handler {
//MARK: - Adapter
func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
if let url = urlRequest.url {
guard let accessToken = self.getAccessToken() else { return urlRequest }
let newUrl = addOrUpdateQueryStringParameter(url: "\(url)", key: "access_token", value: accessToken)
let newRequest = URLRequest(url: URL(string: newUrl)!)
return newRequest
}
return urlRequest
}
// MARK: - RequestRetrier
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 {
if response.statusCode == 401 {
requestsToRetry.append(completion)
if !isRefreshing {
refreshTokens { [weak self] succeeded, accessToken, refreshToken in
guard let strongSelf = self else { return }
strongSelf.lock.lock() ; defer { strongSelf.lock.unlock() }
if let accessToken = accessToken, let refreshToken = refreshToken {
strongSelf.accessToken = accessToken
strongSelf.refreshToken = refreshToken
strongSelf.updateAccessToken(accessToken: accessToken, refreshToken: refreshToken)
}
strongSelf.requestsToRetry.forEach { $0(succeeded, 0.0) }
strongSelf.requestsToRetry.removeAll()
}
}
} else {
completion(false, 0.0)
}
}
}
因此,基本上错误处理是在should
函数中执行的,而不是在函数中执行的。case(let error)
在我的函数中。您没有验证您的请求。因此,它会让每一个请求都成功。尝试在请求之后但在响应之前添加validate()来验证请求:
self.accessSessionManager.request(...).validate().responseJSON { ... }
您可以找到自定义的方法来更改validate()
函数在其Ok中接受的和不接受的行为,因此我犯了一个非常愚蠢的错误,基本上是完成(false,0,0)
如果should
函数中发生错误,就不会执行。如果它看起来像这样,那么一切都正常:
// MARK: - RequestRetrier
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 {
if response.statusCode == 401 {
requestsToRetry.append(completion)
if !isRefreshing {
refreshTokens { [weak self] succeeded, accessToken, refreshToken in
guard let strongSelf = self else { return }
strongSelf.lock.lock() ; defer { strongSelf.lock.unlock() }
if let accessToken = accessToken, let refreshToken = refreshToken {
strongSelf.accessToken = accessToken
strongSelf.refreshToken = refreshToken
strongSelf.updateAccessToken(accessToken: accessToken, refreshToken: refreshToken)
}
strongSelf.requestsToRetry.forEach { $0(succeeded, 0.0) }
strongSelf.requestsToRetry.removeAll()
}
}
} else {
completion(false, 0.0)
} else {
completion(false,0.0)
}
}
如果响应完成,它将成功,但当我尝试捕获超时错误时,响应未完成,因此添加validate()没有帮助,即使指定了错误代码范围。