閑話不說了,今天來學(xué)習(xí)XcodeMen team的輕量級網(wǎng)絡(luò)庫XMNetworking
前陣子看源碼的時候,還是有點懵逼降瞳,自動昨天自己畫了思維導(dǎo)圖昔瞧,對網(wǎng)絡(luò)層的結(jié)構(gòu)分析了一下吟吝,今天再來看菱父,發(fā)現(xiàn)就豁然開朗了,感覺挺好的
XMConst 文件
一個定義全局文件變量文件,用結(jié)構(gòu)體定義了上傳浙宜、下載官辽、普通三種請求方式,6種請求方法粟瞬,3種請求序列化的方式同仆,4種回應(yīng)序列化的方式,三大類請求block(單個請求裙品、批量請求俗批、鏈?zhǔn)秸埱螅┮约耙粋€用來對請求回應(yīng)做處理的通用block,這應(yīng)該都是好理解的清酥。
XMRequest
XMRequest文件定義了XMRequest扶镀、XMBatchRequest蕴侣、XMChainRequest焰轻、XMUploadFormData四個類。
XMRequest 主要是提供請求的配置信息昆雀,也就是請求方法辱志、頭部、URL狞膘、請求和回應(yīng)序列化方式揩懒、超時時間等,還有另外幾個 readonly 修飾的block類型屬性挽封,這幾個block會在請求落地時候調(diào)用并返回業(yè)務(wù)數(shù)據(jù)已球。還有用語上傳數(shù)據(jù)的 uploadFormDatas 屬性,這個屬性規(guī)定了數(shù)組里的對象必須是uploadFormDatas 對象辅愿。還提供了幾個快速添加 uploadFormData的方法
XMBatchRequest智亮、XMChainRequest 并沒有使用繼承的方式,而是采用了組合点待。這兩個請求類通過持有XMRequest 對象作為屬性來獲得XMRequest對象的特征阔蛉,同時又可以自己衍生自己的特性。
XMUploadFormData為上傳請求的數(shù)據(jù)對象癞埠,并提供了多個類方法來創(chuàng)建新對象
整體來說状原,XMRequest文件提供的都是請求起飛的配置。
XMCenter
XMCenter文件定義了兩個類苗踪,分別是XMCenter和XMConfig颠区。
XMConfig類是XMCenter的配置類,而這些XMCenter配置信息通铲,又被間接提供到了request手里毕莱。
XMCenter類是整個框架的核心類,并且是個單例類。將通過請求的流程來分析源碼央串。
1磨澡、 - (void)setupConfig:(void(^)(XMConfig *config))block;
方法提供的config對象完成XMCenter的基本配置信息,這樣XMCenter單例對象將能直接使用這些配置。
2质和、 - (void)setResponseProcessBlock:(XMCenterResponseProcessBlock)block;
這個方法將用來處理返回的response稳摄,注意,這個block會在返回成功之前調(diào)用饲宿,我們可以通過這個block來處理請求成功厦酬,但是業(yè)務(wù)出現(xiàn)錯誤的情況,并且創(chuàng)建一個NSError實例傳遞給block瘫想,這樣在回調(diào)的block中仗阅,就直接走 FailureBlock,而不走SuccessBlock。也就是劫持response国夜,主動改變response走向减噪。
3、接下來就是一連串的便利請求發(fā)起方法车吹,但這些請求發(fā)起方法的下一層筹裕,就是參數(shù)最后的那個方法,也就是這個
- (NSUInteger)sendRequest:(XMRequestConfigBlock)configBlock
onProgress:(nullable XMProgressBlock)progressBlock
onSuccess:(nullable XMSuccessBlock)successBlock
onFailure:(nullable XMFailureBlock)failureBlock
onFinished:(nullable XMFinishedBlock)finishedBlock;
其余調(diào)起請求的方法窄驹,只是在這個方法上封裝了一層朝卒,并且固定了一些參數(shù),所以叫做便利方法乐埠。這個方法的實現(xiàn)如下
XMRequest *request = [XMRequest request];
XM_SAFE_BLOCK(configBlock, request);
[self xm_processRequest:request onProgress:progressBlock onSuccess:successBlock onFailure:failureBlock onFinished:finishedBlock];
return [self xm_sendRequest:request];
這個方法的實現(xiàn)了抗斤,生成了一個XMRequest實例request,并且通過XM_SAFE_BLOCK(configBlock, request);
調(diào)用configBlock(這個是request的配置block丈咐,不要別錯看成XMcenter)瑞眼,將調(diào)起這個接口時候,配置的request信息(接口名字扯罐、請求方法负拟、參數(shù)等),填充到這request實例上來歹河。
4掩浙、再接下來就是通過為接口調(diào)起時配置的request做修飾,可能是新的參數(shù)秸歧、Header厨姚,URL等這些。
5键菱、處理完了request谬墙,那就是帶著request起飛了,也就是這個方法:
- (NSUInteger)xm_sendRequest:(XMRequest *)request
這個方法的實現(xiàn),將調(diào)用另外 XMEngine 來實現(xiàn)真正的起飛拭抬。并且通過block來接收回調(diào)處理部默。返回值將和對應(yīng)的請求task相互綁定,用于取消請求的操作造虎。
6傅蹂、回調(diào)方法有成功和失敗兩種。但在執(zhí)行回調(diào)時候算凿,是在一個私有線程份蝴,也就是XCenter自己的線程種callbackQueue。并且失敗的回調(diào)還有機(jī)會再次讓request起飛氓轰。
7婚夫、回調(diào)函數(shù)之行完成之后,就需要清理回調(diào)的block署鸡,回調(diào)的block是和request成員案糙,所有需要調(diào)用request的 - (void)cleanCallbackBlocks
方法,置空與回調(diào)相關(guān)block(successBlock ;failureBlock ; finishedBlock ;progressBlock 储玫。
8侍筛、鏈?zhǔn)秸埱蠛团空埱螅^程都差不多撒穷,只在請求發(fā)起時候稍有差別。
整個流程差不多這樣了裆熙,在看看代碼端礼,應(yīng)該是沒問題了。并且入录,作者的注釋本來還有使用方法也寫得很清楚了蛤奥。
XMEngine
XMEngine是請求的發(fā)起者,它的下層是依賴于AFNetworking僚稿。并且凡桥,也是一個單例類。
這里應(yīng)該是延續(xù)上面的第5步操作:
5.1 XMEngine對象拿到request對象蚀同,通過request的屬性缅刽,確認(rèn)請求方式是上傳、下載還是普通請求蠢络、請求方法衰猛、序列化方式、超時時間刹孔、業(yè)務(wù)參數(shù)以及全局參數(shù)(Header啡省、agent等),并使用AFHTTPRequestSerializer 的實例對象 生成NSMutableURLRequest類型的URLRequest。如果出現(xiàn)序列化失敗卦睹,那么將會直接進(jìn)入失敗的回調(diào)函數(shù)中畦戒。(作者這里處理序列化失敗回調(diào)時候,使用了一個異步線程)
5.2 調(diào)用AFNetkworking 的sessionManager 并且請求飛起來结序。這其中兢交,通過objc的runtime的 關(guān)聯(lián)對象方法OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
給起飛的請求task將request綁定到了task,算是添加了一個屬性吧笼痹。
5.3 通過task的identifier配喳,從sessionManager的tasks數(shù)組中,找到對應(yīng)identifier的task凳干,進(jìn)行改任務(wù)的取消操作晴裹。這個過程,這這通過 信號量(dispatch_semaphore_...)機(jī)制做了線程安全的處理救赐。
總結(jié)
對這個輕量級的網(wǎng)絡(luò)框架分析就差不多這樣了涧团,總結(jié)一下自己對這個框架的認(rèn)識:
1、這個框架屬于集中型的設(shè)計经磅,請求都是通過XMCenter進(jìn)行調(diào)度
2泌绣、大量使用了block(簡直廢話??),所以有時候看起來的確有點跳,習(xí)慣就好了
3预厌、框架也是組織request阿迈,request起飛,response落地三步走轧叽,所以從這個方向去理解苗沧,就容易多了
4、感謝作者的貢獻(xiàn)炭晒,看源碼還是好處多多待逞,學(xué)習(xí)了!
5网严、有理解錯誤的地方识樱,歡迎指正