Alamofire4.x開原始碼分析(五)進階用法
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
轉載於:https://my.oschina.net/roycehe/blog/1305425