Alamofire基于URLSession和Foundation URL的加载机制,为了更充分的了解和使用本框架,建议大家深刻的学习底层的网络实现.
建议阅读
- URL Loading System Programming Guide
- URLSession Class Reference
- URLCache Class Reference
- URLAuthenticationChallenge Class Reference
Session Manager
Alamofire.request就是我们最外层的方法方法,内部通过Alamofire.SessionManager和默认的URLSessionConfiguration实现
下面两者是等价的
Alamofire.request("https://httpbin.org/get")
let sessionManager = Alamofire.SessionManager.default
sessionManager.request("https://httpbin.org/get")
通过URLSessionConfiguration我们可以自由的修改http请求头,超时时间等.应用程序可以未后台和临时会话创建管理器
Creating a Session Manager with Default Configuration
let configuration = URLSessionConfiguration.default
let sessionManager = Alamofire.SessionManager(configuration: configuration)
Creating a Session Manager with Background Configuration
let configuration = URLSessionConfiguration.background(withIdentifier: "com.example.app.background")
let sessionManager = Alamofire.SessionManager(configuration: configuration)
Creating a Session Manager with Ephemeral Configuration
let configuration = URLSessionConfiguration.ephemeral
let sessionManager = Alamofire.SessionManager(configuration: configuration)
自定义Session Configuration
var defaultHeaders = Alamofire.SessionManager.defaultHTTPHeaders
defaultHeaders["DNT"] = "1 (Do Not Track Enabled)"
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = defaultHeaders
let sessionManager = Alamofire.SessionManager(configuration: configuration)
对于Authorization和Content-Type,不建议通过configuration来修改,Alamofire.request API提供的header来配置.
Session Delegate
默认情况下,Alamofire SessionManager会创建一个SessionDelegate对象来处理URLSession生成的所有各种回调,从中抽出最简单的实现方法. 对于特定需求的开发者,需要覆盖这些方法. ####重写闭包 第一种自定义SessionDelegate方法是重写闭包,每个闭包都对应着SessionDelegate的实现. 举例
/// Overrides default behavior for URLSessionDelegate method `urlSession(_:didReceive:completionHandler:)`.
open var sessionDidReceiveChallenge: ((URLSession, URLAuthenticationChallenge) -> (URLSession.AuthChallengeDisposition, URLCredential?))?
/// Overrides default behavior for URLSessionDelegate method `urlSessionDidFinishEvents(forBackgroundURLSession:)`.
open var sessionDidFinishEventsForBackgroundURLSession: ((URLSession) -> Void)?
/// Overrides default behavior for URLSessionTaskDelegate method `urlSession(_:task:willPerformHTTPRedirection:newRequest:completionHandler:)`.
open var taskWillPerformHTTPRedirection: ((URLSession, URLSessionTask, HTTPURLResponse, URLRequest) -> URLRequest?)?
/// Overrides default behavior for URLSessionDataDelegate method `urlSession(_:dataTask:willCacheResponse:completionHandler:)`.
open var dataTaskWillCacheResponse: ((URLSession, URLSessionDataTask, CachedURLResponse) -> CachedURLResponse?)?
以下是如何使用taskWillPerformHTTPRedirection避免重定向到任何apple.com的问题
let sessionManager = Alamofire.SessionManager(configuration: URLSessionConfiguration.default)
let delegate: Alamofire.SessionDelegate = sessionManager.delegate
delegate.taskWillPerformHTTPRedirection = { session, task, response, request in
var finalRequest = request
if
let originalRequest = task.originalRequest,
let urlString = originalRequest.url?.urlString,
urlString.contains("apple.com")
{
finalRequest = originalRequest
}
return finalRequest
}
###子类覆盖父类方法 另一种方法就是通过子类来重写父类方法
class LoggingSessionDelegate: SessionDelegate {
override func urlSession(
_ session: URLSession,
task: URLSessionTask,
willPerformHTTPRedirection response: HTTPURLResponse,
newRequest request: URLRequest,
completionHandler: @escaping (URLRequest?) -> Void)
{
print("URLSession will perform HTTP redirection to request: \(request)")
super.urlSession(
session,
task: task,
willPerformHTTPRedirection: response,
newRequest: request,
completionHandler: completionHandler
)
}
}
####Request request,download, upload stream这四个方法的返回值分别为DataRequest, DownloadRequest, UploadRequest StreamRequest,并且他们都继承自Request.每个子类都有专用的方法,如authenticate,validate,responseJSON和uploadProgress,都会返回调用者的实例,方便使用. Request可以被暂停,恢复,取消:
- suspend() 暂停
- resume() 恢复, 在SessionManager中有一个属性:startRequestsImmediately。他控制这请求是不是立刻发起,默认的值为true。
- cancel() 取消 同时该请求的每一个监听对象都会受到一个错误回调
####Routing Requests 随着应用程序的扩展,在构建网络堆栈时,采用通用模式很重要. 该设计的重要部分是如何路由您的请求. Alamofire URLConvertible和URLRequestConvertible协议以及路由器设计模式就是为之设计的. 路由的概念就是中转站的意思,在Alamofire中,String, URL, URLComponents实现了URLConvertible协议.
let urlString = "https://httpbin.org/post"
Alamofire.request(urlString, method: .post)
let url = URL(string: urlString)!
Alamofire.request(url, method: .post)
let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true)!
Alamofire.request(urlComponents, method: .post)
采用URLConvertible协议的类型可用于构造URL,然后用于内部构造URL请求。 默认情况下,string,URL和URLComponent准守URLConvertible协议,允许将任何一个作为URL参数传递发送请求,上传和下载等方法:
let urlString = "https://httpbin.org/post"
Alamofire.request(urlString, method: .post)
let url = URL(string: urlString)!
Alamofire.request(url, method: .post)
let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true)!
Alamofire.request(urlComponents, method: .post)
遵守URLConvertible协议,可以方便我们便捷的使用model与服务器生成映射关系.
extension User: URLConvertible {
static let baseURLString = "https://example.com"
func asURL() throws -> URL {
let urlString = User.baseURLString + "/users/\(username)/"
return try urlString.asURL()
}
}
let user = User(username: "mattt")
Alamofire.request(user) // https://example.com/users/mattt