Alamofire-Adapter适配器

Adapter源码分析

  • 在实际开发过程中,我们经常需要在header中添加token的需求,以及非法域名的拦截,接下来就看看Alamofire中应该如何处理?
  • 首先发起一个网络请求:
      SessionManager.default.request(urlStr, method: .get, parameters: ["username":"蓉儿","password":"888888"])
          .response { (response) in
              debugPrint(response)
          }
  • 源码分析可知,在发起请求的时候,用到了一个adapter参数:
    open func request(_ urlRequest: URLRequestConvertible) -> DataRequest {
        var originalRequest: URLRequest?

        do {
            originalRequest = try urlRequest.asURLRequest()
            let originalTask = DataRequest.Requestable(urlRequest: originalRequest!)

            let task = try originalTask.task(session: session, adapter: adapter, queue: queue)
            let request = DataRequest(session: session, requestTask: .data(originalTask, task))

            delegate[task] = request

            if startRequestsImmediately { request.resume() }

            return request
        } catch {
            return request(originalRequest, failedWith: error)
        }
    }
  • 那么adapter到底做了什么?
    struct Requestable: TaskConvertible {
        let urlRequest: URLRequest

        func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask {
            do {
                let urlRequest = try self.urlRequest.adapt(using: adapter)
                return queue.sync { session.dataTask(with: urlRequest) }
            } catch {
                throw AdaptError(error: error)
            }
        }
    }
  • 继续跟进:
    func adapt(using adapter: RequestAdapter?) throws -> URLRequest {
        guard let adapter = adapter else { return self }
        return try adapter.adapt(self)
    }
  • 判断adapter如果存在,调用自己;不存在就返回self。是不是想到了什么?

我们可以通过它,对所有网络请求添加全局参数
可以做重定向
此时有新问题了,在发起请求时,初始化方法并没有这个参数,那么adapter是什么时候赋值的?仔细查找发现对外开放了adapter属性:

    open var adapter: RequestAdapter?

全局参数header设置

  • 我们自定义一个RequestAdapter,注意传入的urlRequest是不可变,所以要var一个新变量再返回:
class DDAdapter: RequestAdapter {
    func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
        var request = urlRequest
        request.setValue("3d335234sfirkjer34cv834d4gvx3", forHTTPHeaderField: "token")
       return request
    }
}
  • 在封装的网络基类,设置adapter,就实现了全局header中添加参数:
SessionManager.default.adapter = DDAdapter()
        SessionManager.default.request(urlStr, method: .get, parameters: ["username":"蓉儿","password":"888888"])
            .response { (response) in
                debugPrint(response)
            }

重定向

  • header设置,只是需要稍微做下手脚,
class DDAdapter: RequestAdapter {
    func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
        var request = urlRequest
        request.setValue("3d335234sfirkjer34cv834d4gvx3", forHTTPHeaderField: "token")
        if (!(request.url!.absoluteString.contains("www.test.com"))) {
            print("非法URL")
            let newUrlRequest = URLRequest.init(url: URL(string: "http://www.baidu.com")!)
            return newUrlRequest
        }
       return request
    }
}
  • 如果符合条件www.test.com就进行重定向,做额外进行处理,实现了非法域名的拦截!

以上就是Adapter的两种用法,
request设置header
request重定向

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。