【问题标题】:Alamofire retry doesn't work with validate()Alamofire 重试不适用于 validate()
【发布时间】:2022-01-03 21:21:16
【问题描述】:

我开始学习 Swift 和 Alamofire。但是我遇到了 RequestInterceptor 的问题:retry func 不起作用。 我的请求拦截器:

class MyRequestInterceptor: RequestInterceptor {
    // MARK: - ADAPT
    func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
        print("-------ADAPT---------")
        var request = urlRequest
        guard let token = TokenService.getAccess() else {
            return
        }
        let bearerToken = "Bearer \(token)"
        request.setValue(bearerToken, forHTTPHeaderField: "Authorization")
        completion(.success(request))
    }
    
    // MARK: - RETRY
    func retry(_ request: Request, for session: Session, dueTo error: ApiError, completion: @escaping (RetryResult) -> Void) {
        print("--------RETRY-------")
        guard let refresh = TokenService.getRefresh() else {
            completion(.doNotRetry)
            return
        }
        let parameter = Refresh(token: refresh)
        AF.request(ApiManager.refresh.path, method: .post, parameters: parameter)
            .responseDecodable(of: TokensPair.self) { response in
                guard let tokens = response.value else {
                    completion(.doNotRetry)
                    return
                }
                TokenService.setAccess(token: tokens.access)
                TokenService.setRefresh(token: tokens.refresh)
                completion(.retry)
            }
    }
}

我的会话管理器:

class SessionManager {
    static let shared = SessionManager()
    
    let sessionManager: Session = {
        let configuration = URLSessionConfiguration.af.default
        configuration.timeoutIntervalForRequest = 30
        configuration.waitsForConnectivity = true
        return Session(
            configuration: configuration,
            interceptor: MyRequestInterceptor()
        )
    }()
}

我的要求:

    func checkUser(complition: @escaping (Result<User, ApiError>) -> Void) {
        SessionManager.shared.sessionManager.request(ApiManager.me.path).validate().responseDecodable(of: User.self) {
            response in
            guard let user = response.value else {
                complition(.failure(.invalidCred))
                return
            }
            complition(.success(user))
        }
    }

Adapt 工作正常。但重试永远不会奏效。我究竟做错了什么? 我正在使用validate() 并期望状态代码:401 会导致错误,导致重试,但它不起作用。 我认为重试实施存在问题。因为当我尝试替换时

class MyRequestInterceptor: RequestInterceptor

class MyRequestInterceptor: RequestRetrier, RequestAdapter

我得到错误:

Type 'MyRequestInterceptor' does not conform to protocol 'RequestRetrier'

但我不知道为什么。我没有找到解决办法。

我使用: Xcode 13.2.1, 斯威夫特:5, Alamofire:5.4.4。

谢谢!

【问题讨论】:

    标签: swift xcode swiftui alamofire swift5


    【解决方案1】:

    您在retry 方法签名中使用了ApiError,这破坏了一致性。它适用于RequestInterceptor,因为该类型提供了默认实现。匹配正确的签名,确保没有本地类型影响签名中的类型,并且它应该可以正常工作。

    【讨论】:

    • 谢谢。但它不起作用。我从 Alamofire 复制重试方法签名,但仍然出现错误:Type 'MyRequestInterceptor' does not conform to protocol 'RequestRetrier' And retry doesn't work after 401 error.
    • 如果编译器仍在抱怨,您要么没有使用正确的签名,要么在本地隐藏了其中一种类型,因此请确保您没有自己的Request、@ 987654325@、ErrorRetryResult 类型。
    • 谢谢!我替换了签名,它现在可以工作了。
    猜你喜欢
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    • 2019-01-03
    • 1970-01-01
    • 1970-01-01
    • 2018-10-08
    • 2019-03-14
    相关资源
    最近更新 更多