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
重定向