1. Alamofire結(jié)構(gòu)
Alamofire全部實現(xiàn)共有17個文件組成,如下:
--------接口----------
Alamofire.swift // api 聲明
--------請求----------
Request.swift // 請求類,用于構(gòu)建請求
ParameterEncoding.swift // 參數(shù)編碼
MultipartFormData.swift // 自定義表單類
ServerTrustPolicy.swift // 服務(wù)器驗證
--------響應(yīng)-----------
Response.swift // 相應(yīng)類,用于構(gòu)建響應(yīng)
ResponseSerialization.swift // 響應(yīng)數(shù)據(jù)序列化
Validation.swift // 響應(yīng)數(shù)據(jù)驗證
Result.swift // 請求結(jié)果表示
AFError.swift // 錯誤類型
--------底層-----------
SessionManager.swift // 請求session的管理類,底層使用NSURLSession實現(xiàn)
SessionDelegate.swift // 請求Session的代理對象,主要實現(xiàn)NSURLSession的代理方法以及回調(diào)閉包
TaskDelegate.swift // 請求Task任務(wù)的代理對象,主要實現(xiàn)NSURLDataTask的代理方法
DispatchQueue+Alamofire.swift //GCD擴展,定義多個不同功能的隊列
---------其他-----------
NetworkReachabilityManager.swift // 網(wǎng)絡(luò)狀態(tài)監(jiān)聽類
Notifications.swift // 定義通知
Timeline.swift //描述請求有關(guān)的時間 結(jié)構(gòu)體
Alamofire有五模塊組成,即接口、請求、響應(yīng)、底層和其他。分析各模塊的實現(xiàn),功能和聯(lián)系就可以理解Alamofire。
2. Alamofire源碼分析
2.1 Alamofire.swift文件
查看源碼可以發(fā)現(xiàn)分為兩部分:
- 一部分主要是協(xié)議的定義和相關(guān)URL轉(zhuǎn)換,如String,URL,URLComponent轉(zhuǎn)URL,并且拋出異常。
- 另一部分,定義公開的接口,分別是數(shù)據(jù)請求(Data Request)、下載請求(Download Request)、上傳請求(Upload Request)和流傳輸請求(Stream Request)。
主要分析第二部分:
-
@discardableResult
作用忽略返回值警告。 - 所有方法的調(diào)用都需要使用
SessionManager.default.xxx
。這說明SessionManager
是所有請求的入口和管理中心。 - 每個請求都會返回XXXRequest對象,關(guān)于XXXRequest對象,在后面會分析。
2.2 Request.swift文件
上面提到每個請求的返回值都是XXXRequest類型。
在Request.swift
文件中定義了五個類,分別是Request、DataRequest、DownloadRequest、UploadRequest和StreamRequest。其中Request為基類。
2.2.1 Request類
基類Request,定義了與HTTP請求相關(guān)的屬性和方法。
- 屬性 :代理delegate(TaskDelegate)和Foundation框架中與URL請求相關(guān)的四個屬性,分別是task(URLSessionTask)、session(URLSession)、request(URLRequest)和response(HTTPURLResponse)。除此之外,還有重試請求次數(shù)retryCount、請求開始時間startTime和結(jié)束時間endTime,以及驗證閉包validations。
-
方法 :基類Request提供初始化方法
init(session: URLSession, requestTask: RequestTask, error: Error? = nil)
默認(rèn)訪問權(quán)限internal
,一般是SessionManager
調(diào)用創(chuàng)建request
,外部不需要創(chuàng)建。另外還有三個服務(wù)器驗證和三個請求狀態(tài)的方法resume()
、suspend()
和cancel()
,其作用是調(diào)用成員屬性task和發(fā)送對應(yīng)的通知,如Notification.Name.Task.DidResume。 -
其他 :另外,還有實現(xiàn)了兩個協(xié)議
CustomStringConvertible
和CustomDebugStringConvertible
。前者定義description
包含了http方法、url和響應(yīng)狀態(tài)碼,后者是比較具體的debug。
2.2.2 DataRequest類
子類DataRequest,管理底層的URLSessionDataTask
。主要用于簡單的HTTP請求,GET和POST等。
- 屬性 :其中包含三個屬性,request(URLRequest)、progress和dataDelegate,其中dataDelegate必須向下轉(zhuǎn)換(as!)為DataTaskDelegate類型。
-
方法 : 另外,還有兩個方法
open func stream(closure: ((Data) -> Void)? = nil) -> Self
和open func downloadProgress(queue: DispatchQueue = DispatchQueue.main, closure: @escaping ProgressHandler) -> Self
分別用來設(shè)置流閉包和下載進度閉包操作。
2.2.3 DownloadRequest類
子類DownloadRequest,管理底層URLSessionDownloadTask
。實現(xiàn)下載請求。包含三個部分輔助類型、屬性、和方法。
- 輔助類型 : DownloadOption(OptionSet)用于移動下載文件從臨時URL到目標(biāo)URL。閉包類型DownloadFileDestination決定下載請求完成后臨時文件寫入的位置。兩個參數(shù):臨時文件URL和URL Response。兩個返回值參數(shù):目標(biāo)URL和定義如何移動(DownloadOptions)。枚舉類型Downloadable。
- 屬性 :request(URLRequest)、resumeData(暫?;蛘呤?,用于重新開啟)、progress(下載進度)和 downloadDelegate(下載代理)。
-
方法 :
open override func cancel()
和open func downloadProgress(queue: DispatchQueue = DispatchQueue.main, closure: @escaping ProgressHandler) -> Self
。前者用于取消下載,后者設(shè)置下載過程的閉包和執(zhí)行隊列。
2.2.4 UploadRequest類
上傳請求,DataRequest的子類。三個屬性,一個方法。
- 屬性 : request(URLRequest)、uploadPregress(上傳進度)和uploadDelegate(上傳代理)
-
方法 :
open func uploadProgress(queue: DispatchQueue = DispatchQueue.main, closure: @escaping ProgressHandler) -> Self
后者設(shè)置上傳過程的閉包和執(zhí)行隊列。
2.2.5 StreamRequest類
流請求,沒有定義屬性和方法,是Request的子類。
2.2.6 對比
對比四個子類,他們對應(yīng)普通請求、下載請求、上傳請求和流傳輸請求。我們注意到一些相似之處,
- 他們都有遵循TaskConvertble協(xié)議的枚舉類型。 其中唯一的方法:
task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask
,用于創(chuàng)建對應(yīng)的task,并對urlRequest做適配。 - Request的delegate/taskDelegate與各個子類中的XXXTaskDelegate的作用是相同的,就是用于創(chuàng)建
TaskDelegate.swift
文件中的各種代理實例,用來處理URLSessionDelegate
的請求。稍后我們在分析TaskDelegate.swift
。
2.3 ParameterEncoding.swift文件
由名字可以理解該文件負(fù)責(zé)對請求參數(shù)進行轉(zhuǎn)碼,如:URL轉(zhuǎn)碼、JSON轉(zhuǎn)碼和PropertyList轉(zhuǎn)碼。三種轉(zhuǎn)碼對應(yīng)三個結(jié)構(gòu)體:URLEncoding
,JSONEncoding
和PropertyListEncoding
。他們都遵循ParameterEncoding
協(xié)議。協(xié)議只有一個方法:func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest
, 把參數(shù)轉(zhuǎn)成目標(biāo)格式,另外還設(shè)置HTTP頭部的信息。例如Content-Type:application/json
。
2.4 MultipartFormData.swift文件
構(gòu)建用于在HTTP或HTTPS主體中上傳的multipart/form-data。 目前有兩種編碼多部分表單數(shù)據(jù)的方式。 第一種方法是直接在內(nèi)存中編碼數(shù)據(jù)。 這是非常有效的,但如果數(shù)據(jù)集太大,可能會導(dǎo)致內(nèi)存問題。 第二種方式是設(shè)計用于較大的數(shù)據(jù)集,并將所有數(shù)據(jù)寫入磁盤上的單個文件,并具有所有正確的邊界分割。 第二種方法必須用于較大的數(shù)據(jù)集,如視頻內(nèi)容,否則,當(dāng)您嘗試對數(shù)據(jù)集進行編碼時,應(yīng)用程序可能會耗盡內(nèi)存。
有關(guān)multipart/form-data的更多信息,請參考RFC-2388和RFC-2045規(guī)范以及w3表單文檔。
- https://www.ietf.org/rfc/rfc2388.
- https://www.ietf.org/rfc/rfc2045.
- https://www.w3.org/TR/html401/interact/forms.html#h-17.13
涉及到的知識比較深,需要補充一下。開個坑,以后填!
2.5 ServerTrustPolicy.swift文件
服務(wù)器驗證。開個坑,以后填!
2.6 Response.swift文件
Response.swift中,有四個結(jié)構(gòu)體,分別是DefaultDataResponse/DataResponse, DefaultDownloadResponse/DownloadResponse。 其中Default是未經(jīng)格式化的。前兩個用于普通數(shù)據(jù)請求和上傳,后倆個用于下載。主要功能是存儲響應(yīng)相關(guān)值。
2.6.1 DefaultDataResponse/DataResponse結(jié)構(gòu)體
- s屬性 :有五個屬性request(URLRequest)、response(HTTPURLResponse)、data(返回的數(shù)據(jù))、error(請求錯誤信息)和timeline(請求時間線,對應(yīng)Timeline.swift)。
-
DataResponse
比DefaultDataResponse
多兩個屬性:value(result.value)和result(序列化數(shù)據(jù))。其他屬性相同。
2.6.2 DefaultDownloadResponse/DownloadResponse結(jié)構(gòu)體
- 屬性 : 有七個屬性,request(URLRequest)、response(HTTPURLResponse)、temporaryURL(臨時地址)、destinationURL(最終地址/重定向地址)、resumeData(下載取消時的contentOffset)、error(請求錯誤信息)和timeline(請求時間線,對應(yīng)Timeline.swift)
-
DownloadResponse
同樣多了兩個屬性。
2.6.3 對比
無論是DataResponse還是DownloadResponse都有兩個方法:public func map<T>(_ transform: (Value) -> T) -> XXXResponse<T>
和public func flatMap<T>(_ transform: (Value) throws -> T) -> XXXResponse<T>
用于數(shù)據(jù)轉(zhuǎn)化,區(qū)別在于后者會拋出異常。無論是服務(wù)器原始數(shù)據(jù),還是序列化后的數(shù)據(jù),都會被存放在result枚舉的case綁定的元組中,success為泛型,failure為Error。具體內(nèi)容后面在Result.swift中講解。
2.7 ResponseSerialization.swift文件
查看源碼,文件由兩個協(xié)議、兩個結(jié)構(gòu)體和多個extension組成。
--------協(xié)議---------
1. DataResponseSerializerProtocol
2. DownloadResponseSerializerProtocol
--------結(jié)構(gòu)體--------
1. DataResponseSerializer<Value>
2. DownloadResponseSerializer<Value>
--------Request擴展------
0. Timeline
1. Default
2. Data
3. String
4. JSON
5. Property List
- Request擴展中2-5都依賴于擴展1的方法,底層調(diào)用構(gòu)造response,幾種序列化過程基本相同。
具體內(nèi)容,后期補充。
2.8 Result.swift
一個枚舉類型Result,有兩個case: success
和failure
。
- success: 綁定指定的泛型實例
- fialure: 綁定Error
兩個主要的方法
public func map<T>(_ transform: (Value) -> T) -> Result<T>
public func flatMap<T>(_ transform: (Value) throws -> T) -> Result<T>
兩者區(qū)別,前者不會拋出一樣。
2.9 AFError.swift
枚舉類型AFError,包含四個內(nèi)部枚舉:
* ParameterEncodingFailureReason // 參數(shù)編碼錯誤
* MultipartEncodingFailureReason // 表單錯誤
* ResponseValidationFailureReason // 響應(yīng)驗證錯誤
* ResponseSerializationFailureReason // 數(shù)據(jù)序列化錯誤
除了四個內(nèi)部枚舉外,AFError本身還有一個,URL無效錯誤。
另外,還可以通過布爾值判斷是否有錯誤。
AFError.swift涉及到內(nèi)聯(lián)枚舉,枚舉綁定值和提取判斷等。
2.10 Validation.swift
Validation.swift主要用于服務(wù)器響應(yīng)數(shù)據(jù)驗證。
由三個擴展組成: Request擴展,DataRequest擴展,DownloadRequest擴展。第一個是基本驗證,后兩個是對不同的下載需求的驗證。
接下來,看看具體實現(xiàn)了什么?
Request擴展
- 兩個屬性,分別是
acceptableStatusCodes
和acceptableContentTypes
- 兩個方法,分別是
fileprivate func validate<S: Sequence>( statusCode acceptableStatusCodes: S, response: HTTPURLResponse) -> ValidationResult where S.Iterator.Element == Int
和
fileprivate func validate<S: Sequence>( contentType acceptableContentTypes: S, response: HTTPURLResponse, data: Data?) -> ValidationResult where S.Iterator.Element == String
這兩個屬性和方法分別用于驗證StatusCode和ContentType。
DataRequest擴展
四個方法:
-
validate(_:)
: 基礎(chǔ)方法,接收Validation類型閉包,構(gòu)建validationExecution,添加到驗證隊列中。 -
validate(statusCode:)
: 驗證StatusCode -
validate(contentType:)
:驗證ContentType -
validate()
:同時驗證StatusCode和ContentType
2.11 SessionManager.swift/SessionDelegate.swift/TaskDelegate.swift
- SessionManager負(fù)責(zé)Session的創(chuàng)建和管理,請求的創(chuàng)建和發(fā)起
- SessionDelegate/TaskDelegate負(fù)責(zé)處理請求的響應(yīng)
SessionManager共有10個屬性,主要的幾個:
- default : 一個單例,對外的接口都調(diào)用這個實例。
- defaultHTTPHeader: 請求頭,定義了默認(rèn)HTTP頭部信息
- backgroundCompletionHandler: APP進入后臺時完成的閉包,需要手動設(shè)置和調(diào)用。
- queue: 每個Session私有的任務(wù)隊列
接下來是初始化方法,SessionManager初始化過程:
- 1.調(diào)用者通過func request(_ urlRequest: URLRequestConvertible) -> DataRequest方法調(diào)用
- 2.SessionManager通過傳入urlRequest創(chuàng)建適配的urlRequest(Request適配器)
- 3.調(diào)用Request.Requestable.task(:::)創(chuàng)建對應(yīng)SessionTask
- 4.創(chuàng)建對應(yīng)的XXXRequest實例
- 5.將XXXRequest設(shè)置到Delegate[task]下標(biāo)
- 6.開始任務(wù)
另外,還有錯誤處理,重試等內(nèi)容。
補充
1. URL Loading System架構(gòu)
URL加載系統(tǒng)包括加載URL的類,以及一些重要的幫助類。主要的幫助類:協(xié)議支持,身份驗證和憑據(jù),Cookie存儲,配置管理和緩存管理等。
小結(jié)
初步學(xué)習(xí)了Alamofire源碼文件,并沒有深入探究源碼具體實現(xiàn)。后續(xù)內(nèi)容稍后補充,先補補基礎(chǔ)知識。??