AFNetworking源碼閱讀筆記(一)

一、NSURLSession部分

AFHTTPSessionManager繼承自AFURLSessionManager類,主要是對AFURLSessionManager的封裝。

這個類粗體分三部分也就是說有三部分功能:(1)初始化請求類,(2)開放一些請求類的屬性(3)抽象出幾種通常的http請求種類的方法。

(1)初始化請求類:

類方法返回一個AFHTTPSessionManager對象,可用于網(wǎng)絡(luò)請求。

初始化方法,主要是對AFURLSessionManager初始化方法的封裝,在對AFURLSessionManager的介紹中再詳細(xì)解說。

(2)開放一些請求類的屬性:

根URL

請求參數(shù)編碼的序列化器,主要功能是將通常提交的字典參數(shù)根據(jù)不同的請求方式以及不同的數(shù)據(jù)提交格式序列化為相對應(yīng)的字符串。

構(gòu)造好之后將組裝成具體請求方式相對應(yīng)的結(jié)構(gòu),然后提交到傳輸層進行相對應(yīng)的編碼后,再交到會話層。

與requestSerializer相對應(yīng),將返回的結(jié)構(gòu)依次反序列化得到期望的返回數(shù)據(jù)結(jié)構(gòu)(字典,數(shù)組,字符串等)。

設(shè)置安全策略。

(3)抽象出幾種通常的http請求種類的方法:

get類型相關(guān)方法:

參數(shù)URLString:NSString類型,用于構(gòu)造請求URL

參數(shù)parameters:id類型(根據(jù)具體情況可能為字典、字符串、數(shù)組),將會根據(jù)設(shè)置的requestSerializer進行編碼

參數(shù)success:nullable void(^)(NSURLSessionDataTask * task,id_Nullable responseObject的block對象,當(dāng)請求任務(wù)成功執(zhí)行后將被執(zhí)行,responseObject為網(wǎng)絡(luò)請求返回的參數(shù)根據(jù)設(shè)置的response serializer反編碼后得到的期望的數(shù)據(jù)結(jié)構(gòu)id類型(根據(jù)具體情況可能為字典、字符串、數(shù)組

參數(shù)failure:nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error)類型的block對象,當(dāng)請求任務(wù)失敗后將被執(zhí)行,error會記錄相關(guān)錯誤類型。

參數(shù)downloadProgress:nullable void(^)(NSProgress *downloadProgress)類型的block對象,當(dāng)下載進度更新時會調(diào)用,在當(dāng)前的會話隊列中執(zhí)行,不是在主隊列中執(zhí)行。

post類型相關(guān)方法:

參數(shù)URLString:NSString類型,用于構(gòu)造請求URL

參數(shù)parameters:id類型(根據(jù)具體情況可能為字典、字符串、數(shù)組),將會根據(jù)設(shè)置的requestSerializer進行編碼

參數(shù)success:nullable void(^)(NSURLSessionDataTask * task,id_Nullable responseObject的block對象,當(dāng)請求任務(wù)成功執(zhí)行后將被執(zhí)行,responseObject為網(wǎng)絡(luò)請求返回的參數(shù)根據(jù)設(shè)置的response serializer反編碼后得到的期望的數(shù)據(jù)結(jié)構(gòu)id類型(根據(jù)具體情況可能為字典、字符串、數(shù)組

參數(shù)failure:nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error)類型的block對象,當(dāng)請求任務(wù)失敗后將被執(zhí)行,error會記錄相關(guān)錯誤類型。

參數(shù)uploadProgress:nullable void(^)(NSProgress *uploadProgress)類型的block對象,當(dāng)上傳進度更新時會調(diào)用,在當(dāng)前的會話隊列中執(zhí)行,不是在主隊列中執(zhí)行

參數(shù)block:nullable void (^)(id <AFMultipartFormData> ?formData)類型block對象,多用圖片或大文件的單個上傳和批量上傳。參見詳情。??<AFMultipartFormData>可參見詳情

head、patch、put、delete相關(guān)方法:

參見詳情

下面詳細(xì)分析AFURLSessionManager類:

AFNetworking3.0采用了蘋果新出的網(wǎng)絡(luò)框架NSURLSession實現(xiàn),仍使用NSOperation管理請求隊列。

下面從一個調(diào)用開始分析,看看每一步都做了什么:

首先,要初始化:

先看看這個方法

其內(nèi)容和平常的工廠方法沒啥區(qū)別,也是調(diào)用一個傳統(tǒng)的初始化方法:

再深入看

除了給對象本身baseURL、requestSerializer、responseSerializer賦初始值之外,主要來分析一下調(diào)用父類的初始化方法

前邊部分主要是對NSSession請求方式做一個封裝,再給自身相關(guān)屬性賦值,比如網(wǎng)絡(luò)安全策略,必要的鎖等。

最后一個調(diào)用,意義可能是:為了防止后臺回來,重新初始化這個session,一些之前的后臺請求任務(wù),導(dǎo)致程序的crash。參見詳情

然后,就可以使用初始化好的AFHTTPSessionManager來做網(wǎng)絡(luò)請求了:

下面從一個常用的post請求接口開始:

如圖,先構(gòu)造NSURLSessionDataTask *dataTask對象,然后調(diào)用[dataTask resume]方法發(fā)送請求。

下面具體分析這個構(gòu)造方法:


使用請求參數(shù)序列化器self.requestSerializer根據(jù)傳入的根路徑、請求方法和參數(shù)構(gòu)造NSMutableURLRequest對象。

如果構(gòu)造失敗,異步執(zhí)行傳入的failure。如果設(shè)置了self.completionQueue,則在這個隊列中執(zhí)行,否則在dispatch_get_main_queue()主隊列中執(zhí)行,這也是通常的場景。

緊接著根據(jù)之前構(gòu)造的request對象以及傳入的相關(guān)block對象構(gòu)造dataTask,并根據(jù)請求失敗或成功回調(diào)相應(yīng)的block對象。

繼續(xù)深入查看dataTask的構(gòu)造方法:

查看這個方法,應(yīng)該是解決iOS8之前的bug,鑒于現(xiàn)在大部分應(yīng)用支持最低版本都在iOS8之后,不再深究這個方法。

這里通過系統(tǒng)方法通過初始化方法初始化的self.session構(gòu)造dataTask。

下面重點分析

這個調(diào)用,這里也是AFNetworking中特別是NSURLSession部分最核心也最值得贊賞的部分:

下面逐行分析:

可以看出針對每一個dataTask都要創(chuàng)建一個AFURLSessionManagerTaskDelegate ?*delegate對象。

緊接著給相關(guān)屬性賦值。

重要的一點:

這行代碼將dataTask和相關(guān)的delegate對象關(guān)聯(lián)起來,查看源碼:

原來是是AFURLSessionManager維護了一個@property (readwrite, nonatomic, strong) NSMutableDictionary ?*mutableTaskDelegatesKeyedByTaskIdentifier的字典。

這個字典的每一個元素的key值是dataTasktaskIdentifier的標(biāo)示,value則是關(guān)聯(lián)的delegate對象。之前初始化方法中創(chuàng)建的self.lock對象用來保證線程安全。

添加了相關(guān)的監(jiān)聽。

縱上,dataTask就構(gòu)造完整了,執(zhí)行[dataTask resume]方法后將發(fā)起網(wǎng)絡(luò)請求。

下邊開始分析網(wǎng)絡(luò)請求完成后是如何回調(diào)的:

AFURLSessionManager聲明中看出,AFURLSessionManager繼承了NSURLSessionDelegate等相關(guān)協(xié)議,再查看self.session的初始化方法,以及dataTask的構(gòu)造方法,可以看出,網(wǎng)絡(luò)請求完成后是通過調(diào)用NSURLSessionDelegate的相關(guān)方法完成回調(diào)的。

由于這里分析的是dataTask是NSURLSessionDataTask對象,所以在完成請求后必然調(diào)用NSURLSessionTaskDelegate的以下方法:

和之前提到的

方法剛好相對應(yīng):

通過self.mutableTaskDelegatesKeyedByTaskIdentifier字典,根據(jù)dataTasktask.taskIdentifierkey值獲取到之前關(guān)聯(lián)的AFURLSessionManagerTaskDelegate *類型的delegate。

緊接著這里有點迷惑人的地方,作者沒有為AFURLSessionManagerTaskDelegate獨立設(shè)計一個方法,而是繼承了NSURLSessionTaskDelegate協(xié)議,實現(xiàn)

這個協(xié)議方法對單獨的dataTask進行回調(diào)處理。

下面繼續(xù)分析這個方法:


通過delegate之前的賦值,獲取到當(dāng)前的AFURLSessionManager以及相關(guān)的responseSerializer反序列化器。

如果返回error不為空,如果設(shè)置了manager.completionGroupmanager.completionQueue相關(guān)隊列,在其相關(guān)隊列中,否則回到dispatch_get_main_queue()主隊列中回調(diào)請求時設(shè)置的self.completionHandlerblock對象。

如果error不為空,則調(diào)用

反序列化器manager.responseSerializer的解析方法獲取到要返回的數(shù)據(jù)接著和上邊相同,將結(jié)果回調(diào)。

最后,回到

這個最初的dataTask構(gòu)造方法,在completionHandler中通過error是否為空,分別執(zhí)行請求失敗和成功的回調(diào),也就是post請求入口設(shè)置的成功和失敗回調(diào):

結(jié)束之后,

[self removeDelegateForTask:task]這里移除task的相關(guān)關(guān)聯(lián):

和之前的[self delegateForTask:task][self setDelegate:delegateforTask:dataTask]方法相對應(yīng)。

就此一個post網(wǎng)絡(luò)請求完成。

本篇主要是通過一個典型的post方法,梳理出AFNetworking框架中網(wǎng)絡(luò)請求的主干流程,其他網(wǎng)絡(luò)請求方式主干流程也大同小異,畢竟現(xiàn)在關(guān)于這個框架的博客文章數(shù)不勝數(shù),優(yōu)秀文章也比比皆是,所以我選擇的角度就是通過一個網(wǎng)絡(luò)請求流程將主干部分貫通,也就是對NSURLSession模塊做一個梳理。后邊將繼續(xù)分析其他模塊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容