Alamofire源碼分析筆記

Alamofire

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é)議CustomStringConvertibleCustomDebugStringConvertible。前者定義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) -> Selfopen 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,JSONEncodingPropertyListEncoding。他們都遵循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表單文檔。

涉及到的知識比較深,需要補充一下。開個坑,以后填!

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)。
  • DataResponseDefaultDataResponse多兩個屬性: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: successfailure。

  • 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擴展

  • 兩個屬性,分別是acceptableStatusCodesacceptableContentTypes
  • 兩個方法,分別是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 Loading System

URL加載系統(tǒng)包括加載URL的類,以及一些重要的幫助類。主要的幫助類:協(xié)議支持,身份驗證和憑據(jù),Cookie存儲,配置管理和緩存管理等。

小結(jié)

初步學(xué)習(xí)了Alamofire源碼文件,并沒有深入探究源碼具體實現(xiàn)。后續(xù)內(nèi)容稍后補充,先補補基礎(chǔ)知識。??

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Alamofire源碼解讀 AFNetworking的作者Matt Thompson 提出了一個新的類似AFNet...
    spicyShrimp閱讀 1,166評論 0 3
  • Alamofire的基本用法 1.請求 這是一個最簡單的請求,這個請求即不需要參數(shù),也不需要接收數(shù)據(jù)。接下來我們翻...
    水落斜陽閱讀 3,251評論 0 16
  • Alamofire 是一款 Swift 寫的 HTTP 網(wǎng)絡(luò)請求庫 前言 本篇內(nèi)容為 Alamofire 官方 R...
    zongmumask閱讀 20,933評論 6 66
  • 7月6日 星期四 晴 上班的人參加特訓(xùn)營真是傷不起,真想把時間掰成兩半來用!做完作業(yè)其實想讓自己鍛煉一下,參加P...
    雪媚閱讀 392評論 0 0
  • 今天我們share一個超好用了潔面方法。 操作難度 ★★ 清潔指數(shù) ★★★★ 耗費時間 ★★★ 適用人群:主要針對...
    麥小琪閱讀 393評論 0 0