返回
从类层次剖析RequestInterceptor的设计与实现
IOS
2024-02-04 11:14:03
上篇,我们梳理了Alamofire的工作流程。今天我们继续研究,这次主要梳理RequestInterceptor(拦截器)的相关内容。
public protocol RequestInterceptor {
func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void)
func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void)
}
public protocol RequestAdapter: RequestInterceptor {
func adapt(_ urlRequest: URLRequest) -> URLRequest
}
public protocol RequestRetrier: RequestInterceptor {
func retry(_ request: Request, for session: Session, dueTo error: Error) -> Bool
}
public protocol RedirectHandler: RequestInterceptor {
func urlRequest(_ urlRequest: URLRequest, for session: Session, redirectResponse: HTTPURLResponse, completion: @escaping (Result<URLRequest, Error>) -> Void)
}
public protocol EventMonitor: RequestInterceptor {
func request<Value>(_ request: Request, didParseResponse response: HTTPURLResponse, data: Data?, error: Error?)
}
public protocol ServerTrustManager: RequestInterceptor {
func serverTrustManager(for session: Session) -> ServerTrustManaging?
}
public protocol SessionDelegate: RequestInterceptor {
func sessionDidReceiveChallenge(_ session: Session, challenge: URLAuthenticationChallenge, completion: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
}
extension RequestInterceptor {
public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
completion(.success(urlRequest))
}
public func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) {
completion(.doNotRetry)
}
public func urlRequest(_ urlRequest: URLRequest, for session: Session, redirectResponse: HTTPURLResponse, completion: @escaping (Result<URLRequest, Error>) -> Void) {
completion(.success(urlRequest))
}
public func request<Value>(_ request: Request, didParseResponse response: HTTPURLResponse, data: Data?, error: Error?) { }
public func serverTrustManager(for session: Session) -> ServerTrustManaging? {
return nil
}
public func sessionDidReceiveChallenge(_ session: Session, challenge: URLAuthenticationChallenge, completion: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { }
}
RequestInterceptor
类层次结构定义了各种类型的拦截器,它们都可以用来修改请求、响应和任务。
RequestAdapter
:这个协议允许你修改请求。RequestRetrier
:这个协议允许你在请求失败后重试请求。RedirectHandler
:这个协议允许你处理重定向请求。EventMonitor
:这个协议允许你在请求和响应过程中接收事件。ServerTrustManager
:这个协议允许你指定服务器信任管理器。SessionDelegate
:这个协议允许你处理会话委托方法。
你可以使用 SessionConfiguration
的 requestInterceptors
属性来指定要使用的拦截器。例如,下面的代码创建了一个 SessionConfiguration
对象,并指定了一个 RequestAdapter
类型的拦截器。
let configuration = URLSessionConfiguration.default
configuration.requestInterceptors = [MyRequestAdapter()]
你也可以使用 Request
的 requestInterceptors
属性来指定要使用的拦截器。例如,下面的代码创建一个 Request
对象,并指定了一个 RequestAdapter
类型的拦截器。
let request = Request(url: "https://example.com")
request.requestInterceptors = [MyRequestAdapter()]
拦截器可以用于各种各样的场景,例如:
- 添加身份验证标头到请求。
- 修改请求的查询参数。
- 重试失败的请求。
- 处理重定向请求。
- 监听请求和响应事件。
- 指定服务器信任管理器。
- 处理会话委托方法。
RequestInterceptor
类层次结构提供了各种类型的拦截器,它们都可以用来修改请求、响应和任务。你可以使用 SessionConfiguration
的 requestInterceptors
属性或 Request
的 requestInterceptors
属性来指定要使用的拦截器。拦截器可以用于各种各样的场景,例如添加身份验证标头到请求、修改请求的查询参数、重试失败的请求、处理重定向请求、监听请求和响应事件、指定服务器信任管理器和处理会话委托方法。