You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Alamofire中RetryPolicy的adapt方法未触发,如何修改请求超时?

解决方法

1. 让自定义重试策略遵循RequestAdapter协议

你的ConnectionLostRetryPolicy仅继承自RetryPolicy,但RetryPolicy只实现了重试逻辑对应的RequestRetrier协议,你写的adapt只是普通方法,Alamofire无法识别并调用。需要让类显式遵循RequestAdapter协议,才能触发适配逻辑:

open class ConnectionLostRetryPolicy: RetryPolicy, RequestAdapter { // 添加RequestAdapter协议
    public init(retryLimit: UInt = RetryPolicy.defaultRetryLimit,
                exponentialBackoffBase: UInt = RetryPolicy.defaultExponentialBackoffBase,
                exponentialBackoffScale: Double = RetryPolicy.defaultExponentialBackoffScale,
                retryableHTTPMethods: Set<HTTPMethod> = RetryPolicy.defaultRetryableHTTPMethods) {
        super.init(retryLimit: retryLimit,
                   exponentialBackoffBase: exponentialBackoffBase,
                   exponentialBackoffScale: exponentialBackoffScale,
                   retryableHTTPMethods: retryableHTTPMethods,
                   retryableHTTPStatusCodes: [],
                   retryableURLErrorCodes: [.networkConnectionLost])
    }

    // 现在该方法属于RequestAdapter协议的实现,会被Alamofire调用
    public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
        var modifiedRequest = urlRequest
        // 修改超时时间,示例设置为10秒
        modifiedRequest.timeoutInterval = 10.0
        print("ADAPT METHOD CALLED: 已修改请求超时时间")
        completion(.success(modifiedRequest))
    }
}

2. 确保Session正确初始化并被使用

Alamofire的Session是不可变对象,创建后无法修改内部配置,需确保后续所有请求都使用带有自定义拦截器的Session实例:

// 假设你的单例类定义如下
class AlamofireSession {
    static let shared = AlamofireSession()
    var session: Session!
    
    private init() {
        // 初始化默认Session
        session = Session()
    }
}

// 替换为携带自定义拦截器的Session
AlamofireSession.shared.session = Session(interceptor: ConnectionLostRetryPolicy())

// 后续请求必须使用这个Session实例
AlamofireSession.shared.session.request("https://your-api-url.com").response { response in
    // 处理响应逻辑
}

3. 可选方案:拆分Adapter与Retryer

如果不想让重试策略类承担请求适配的职责,可以单独定义Adapter,再用CombineAdapterRetrier组合两者:

// 单独的超时适配器
class TimeoutAdapter: RequestAdapter {
    func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
        var modifiedRequest = urlRequest
        modifiedRequest.timeoutInterval = 10.0
        completion(.success(modifiedRequest))
    }
}

// 原有的重试策略
let retryPolicy = ConnectionLostRetryPolicy()
// 组合适配器与重试器
let interceptor = CombineAdapterRetrier(adapter: TimeoutAdapter(), retrier: retryPolicy)

// 创建Session时使用组合拦截器
AlamofireSession.shared.session = Session(interceptor: interceptor)

关键原因总结

  • 未遵循RequestAdapter协议时,自定义的adapt方法只是普通方法,Alamofire的Session不会主动调用。
  • RetryPolicy仅负责重试逻辑,要实现请求修改(如超时、Header添加),必须关联RequestAdapter协议,或通过组合方式拆分职责。

内容的提问来源于stack exchange,提问作者Sajjad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 08:45:17