没有调用 Alamofire 请求拦截器

Posted

技术标签:

【中文标题】没有调用 Alamofire 请求拦截器【英文标题】:Alamofire request interceptor not being called 【发布时间】:2021-09-28 13:36:31 【问题描述】:

本周添加到我的 Alamofire SO 帖子的长篇大论中,为什么我的 RequestInterceptor 不起作用?适配函数内部的任何内容都不会被调用,但是任何一个函数之外的断点都会被命中。

我开始相信它并不是 RequestInterceptor 本身,因为我复制了一些不同的指南,看看它是否会破坏函数内部,而它们不会。 https://www.avanderlee.com/swift/authentication-alamofire-request-adapter/ https://www.raywenderlich.com/11668143-alamofire-tutorial-for-ios-advanced-usage#toc-anchor-013 https://medium.com/swlh/retry-request-using-alamofire-52c7dcd72175

终于来到了这里,并在那里遵循了一些对问题没有帮助的选项。 https://github.com/Alamofire/Alamofire/issues/2998

这是我的拦截器

import Alamofire

class APIRequestInterceptor: RequestInterceptor 
    
    typealias AdapterResult = Swift.Result<URLRequest, Error>
  
    let retryLimit = 5
    let retryDelay: TimeInterval = 10
  
//    func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Swift.Result<URLRequest, Error>) -> Void) 
    func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (AdapterResult) -> Void) 
//    func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) 
//    func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, AFError>) -> Void) 
        var urlRequest = urlRequest
        
        debugPrint("In the request interceptor...")
        debugPrint(urlRequest)
        
        if let token = Globals.sharedInstance.token 
            urlRequest.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
        
        completion(.success(urlRequest))
    
  
    func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) 
        let response = request.task?.response as? HTTPURLResponse
        //Retry for 5xx status codes
        if
            let statusCode = response?.statusCode,
            (500...599).contains(statusCode),
            request.retryCount < retryLimit 
            completion(.retryWithDelay(retryDelay))
         else 
            return completion(.doNotRetry)
        
    

和我的客户创建会话

static let sessionManager: Session = 
    let configuration = URLSessionConfiguration.af.default
    
    configuration.timeoutIntervalForRequest = 30
    configuration.waitsForConnectivity = true
    
    return Session(configuration: configuration, interceptor: APIRequestInterceptor(), eventMonitors: [APILogger()])
()

为了彻底,请求是使用sessionManager.request(convertible: URLRequestConvertible)提出的

查看请求函数,不知道为什么在请求参数中又定义了一个拦截器? open func request(_ convertible: URLRequestConvertible, interceptor: RequestInterceptor? = nil) -&gt; DataRequest 尽管如此,我也尝试在请求参数中再次定义它,但没有任何运气。 sessionManager.request(route, interceptor: APIRequestInterceptor())

【问题讨论】:

尝试让你的拦截器也成为一个类对象:static let interceptor = APIRequestInterceptor() () 并在创建sessionManager 时使用它:Session(configuration: configuration, interceptor: interceptor, eventMonitors: [APILogger()])? 如果您称自己为sessionManager.request(convertible: URLRequestConvertible),请使用之前评论中新创建的static 调用它。 @Larme 既不单独工作也不联合工作。仍然没有记录 debugPrint 并且没有在适应函数内部断点:( 这些方法也可以在编译时被忽略。确保您没有任何与协议要求的类型(如 RequestSessionResult)冲突的本地类型。 @JonShier 我忽略了传递给 Result 的类型。虽然我没有明确定义自定义结果类型,但由于自定义错误类型,我无意中在方法签名中做了。 【参考方案1】:

事实证明,问题实际上是消歧,但我觉得不太明显。

正在为 Alamofire https://github.com/Alamofire/Alamofire/issues/2998查看此问题

消除歧义 Result 是由于自定义 Result 类型的解决方案。花了一些时间才注意到我有一个自定义错误类型...

我的解决方案是强烈消除两个函数调用的歧义,以防止将来发生这种情况。

func adapt(_ urlRequest: URLRequest, for session: Alamofire.Session, completion: @escaping (Swift.Result<URLRequest, Swift.Error>) -> Void) 

func retry(_ request: Alamofire.Request, for session: Alamofire.Session, dueTo error: Swift.Error, completion: @escaping (RetryResult) -> Void) 

【讨论】:

以上是关于没有调用 Alamofire 请求拦截器的主要内容,如果未能解决你的问题,请参考以下文章

在 swift 3 中下载文件时,alamo fire 中的进度视图不会更新

Alamofire 2 不允许 SSL 连接 Instagram API

使用 Alamofire 进行 GET 请求调用后没有响应

在 post 方法中发送标头

Alamofire 不会自动设置“If-None-Match”标头

用 Alamofire 拦截每一个响应