如何使用 alamofire 重试失败的请求?

Ogu*_*kus 6 ios swift alamofire alamofire-request alamofire5

在没有连接的情况下,我将失败的请求附加到队列管理器(包含数组)

我正在呈现一个带有重试按钮的自定义弹出窗口。当按下重试按钮时,我想重试在无连接状态下无法发送的请求。可能有多个请求。

当我尝试retryRequestAlamofireSession类中的方法时,请求的任务状态保持在 initilazed 或 finish 状态,但必须恢复才能成功发送请求,我该如何解决这种情况?

拦截器接口.swift

    public func didGetNoInternetConnection() {
    let viewModel = AppPopupViewModel(title: L10n.AppPopUp.areYouOffline, description: L10n.AppPopUp.checkInternetConnection, image: Images.noInternetConnection.image, firstButtonTitle: L10n.General.tryAgain, secondButtonTitle: nil, firstButtonAction: { [weak self] in
        guard let self = self else { return }
        DispatchQueue.main.async {
            self.retry()
        }
    }, secondButtonAction: nil, dismissCompletion: nil, dimColor: Colors.appGray.color.withAlphaComponent(0.8), showCloseButton: true, customView: nil)
    DispatchQueue.main.async {
        AppPopupManager.show(with: viewModel, completion: nil)
    }
}

private func retry() {
    
    guard let head = NetworkRequestStorage.shared.head else {
        return
    }
    let request = head.request
    let session = head.session
    session.retryRequest(request, withDelay: nil)
}
Run Code Online (Sandbox Code Playgroud)

API拦截器.swift

final class APIInterceptor: Alamofire.RequestInterceptor {
    private let configure: NetworkConfigurable

    private var lock = NSLock()
    
    // MARK: - Initilize
    internal init(configure: NetworkConfigurable) {
        self.configure = configure
    }

    // MARK: - Request Interceptor Method
    internal func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
        lock.lock()
        defer {
            lock.unlock()
        }
        var urlRequest = urlRequest
        if let token = self.configure.accessToken {
            /// Set the Authorization header value using the access token.
            urlRequest.setValue("Bearer " + token, forHTTPHeaderField: "Authorization")
        }
        // Set Accept-Language header value using language code
        urlRequest.setValue(configure.languageCode, forHTTPHeaderField: "Accept-Language")
        
        // Arrange Request logs for develope and staging environment
        if let reachability = NetworkReachabilityManager(), !reachability.isReachable {
            configure.didGetNoInternetConnection()
            completion(.failure(APIClientError.networkError))
        }
        completion(.success(urlRequest))
    }
    
    
    // MARK: - Error Retry Method
    internal func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) {
        // Arrange Error logs for develope and staging environment
        
        if let aError = error as? APIClientError, aError.statusCode == 400 { // no connection state
            NetworkRequestStorage.shared.enqueue(request: request, session: session)
            completion(.doNotRetryWithError(error))
        } else {
            request.retryCount <= configure.retryCount ? completion(.retry) : completion(.doNotRetryWithError(error))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果请求成功或者没有连接错误,我会将其从NetworkRequestStoroge类中删除。