NSURLSession是iOS7推出的新一代網(wǎng)絡(luò)框架慎璧,在NSURLConnection的基礎(chǔ)上多了一種選擇,AFNetwrking基于NSURLSession也實(shí)現(xiàn)了相應(yīng)的網(wǎng)絡(luò)請(qǐng)求API填具。從功能模塊劃分涣狗,網(wǎng)絡(luò)可用性碑诉,數(shù)據(jù)的序列化和反序列化以及安全策略這幾部分都是一樣的携取,主要是網(wǎng)絡(luò)請(qǐng)求的管理,請(qǐng)求和返回的處理比前者更加簡單送火,應(yīng)該說NSURLSession從系統(tǒng)層面實(shí)現(xiàn)了NSURLConnection沒有實(shí)現(xiàn)的部分拳话,比如管理多個(gè)請(qǐng)求先匪,直接面向應(yīng)用層提供上傳下載的接口种吸,所以AFNetworking基于NSRULSession實(shí)現(xiàn)的網(wǎng)絡(luò)層更簡單,但是功能上沒有NSURLConnection那么豐富呀非,比如監(jiān)聽所有任務(wù)中完成任務(wù)的進(jìn)度坚俗,還有和UIKit的集成。
AFURLSessionManager
NSURLSession
支持多個(gè)用task網(wǎng)絡(luò)請(qǐng)求的管理岸裙,是網(wǎng)絡(luò)層的核心猖败。有NSURLSessionDelegate,NSURLSessionTas
kDelegate,NSURLSessionDataDelegate,NSURLSessionDownloadDelegate 多個(gè)代理接口。operationQueue
用于初始化NSURLSession的隊(duì)列降允,網(wǎng)絡(luò)請(qǐng)求返回的回調(diào)會(huì)在該隊(duì)列中的線程執(zhí)行恩闻。類比使用NSURLConnection的時(shí)候,也有一個(gè)OperationQueue剧董,功能基本一樣幢尚,雖然NSURLConnection自己就是異步線程去發(fā)起網(wǎng)絡(luò)請(qǐng)求,但是如果不使用NSOpeartion和OperationQueue翅楼,網(wǎng)絡(luò)回調(diào)都將正在主線程中執(zhí)行尉剩,會(huì)影響UI操作的流暢性。在NSURLConnection的實(shí)現(xiàn)部分毅臊,是通過全局的網(wǎng)絡(luò)線程去執(zhí)行回調(diào)的理茎。這是NSURLConnection和NSURLSession不太一致的地方,后者是系統(tǒng)層就處理了,比NSURLConnection方便不少皂林。responseSerializer 用于返回?cái)?shù)據(jù)的反序列化的對(duì)象
tasks NSURLSession管理的所有網(wǎng)絡(luò)請(qǐng)求包含重復(fù)的朗鸠,分為一般的api請(qǐng)求,上傳請(qǐng)求和下載請(qǐng)求。
dataTasks 一般的api請(qǐng)求
uploadTasks 上傳請(qǐng)求
downloadTasks 下載請(qǐng)求
completionQueue 用戶端的回調(diào)所在的隊(duì)列
completionGroup 用戶端回調(diào)隊(duì)列所在的組
AFURLSessionManagerTaskDelegagate
在AFURLSessionManager內(nèi)部用于存儲(chǔ)task相關(guān)數(shù)據(jù)的業(yè)務(wù)對(duì)象础倍,詳細(xì)內(nèi)容下面會(huì)單獨(dú)介紹童社。-
mutableTaskDelegatesKeyedByTaskIdentifier 可變字典,用于存儲(chǔ)task和對(duì)應(yīng)delegate之間的關(guān)聯(lián)著隆。
剩下的就是在網(wǎng)絡(luò)請(qǐng)求過程中各種狀態(tài)的回調(diào)block對(duì)象了扰楼。
AFURLSessionManagerTaskDelegate
在網(wǎng)絡(luò)請(qǐng)求的各種回調(diào)過程中,它用來存儲(chǔ)和記錄與單個(gè)task相關(guān)的信息美浦,在網(wǎng)絡(luò)請(qǐng)求完成之后弦赖,將數(shù)據(jù)
返回給用戶端。
AFURLSessionManager
在AFURLSessionManagerTaskDelegate對(duì)象中記錄的session對(duì)象浦辨,一個(gè)session對(duì)象對(duì)應(yīng)這多個(gè)
task對(duì)象蹬竖,每個(gè)task都有一個(gè)與之對(duì)應(yīng)的AFURLSessionManagerTaskDelegate對(duì)象。每一個(gè)task
在session層面都共享了一些數(shù)據(jù)流酬,比如序列化對(duì)象币厕,回調(diào)的隊(duì)列和組,當(dāng)一個(gè)task完成的時(shí)候芽腾,都需要
從共享的session中獲取這些數(shù)據(jù)來完成業(yè)務(wù)層的回調(diào)邏輯旦装。mutableData
存儲(chǔ)了當(dāng)前請(qǐng)求獲得的返回的數(shù)據(jù)信息,最后會(huì)反序列化成對(duì)象或者是以文件的形式保存下來摊滔。progress
記錄了下載或者上傳文件的進(jìn)度阴绢,可以隨時(shí)通過uploadProgressForTask來獲取某個(gè)task完成情況,
該方法參數(shù)為當(dāng)前task艰躺。AFURLSessionTaskCompletionHandler 由用戶端設(shè)置的呻袭,task請(qǐng)求完成之后的用戶端回調(diào)block
AFURLSessionDownloadTaskDidFinishDownloadingBlock
由用戶端設(shè)置的,task下載文件完成之后生成目標(biāo)文件的保存路徑的blockdownloadFileURL
由上一個(gè)block生成的目標(biāo)文件保存路徑腺兴,在下載完成的回調(diào)中設(shè)置左电,然后在整個(gè)請(qǐng)求完成的回調(diào)中以通知的形式返回給用戶端
AFURLSessionManager與AFURLSessionManagerTaskDelegate的關(guān)系
在AFURLSessionManager中實(shí)現(xiàn)了大部分NSURLSession的協(xié)議,而AFURLSessionManagerTaskDelegate也實(shí)現(xiàn)了幾個(gè)重要的協(xié)議页响,比如數(shù)據(jù)獲取篓足,整個(gè)task請(qǐng)求完成,文件下載和上傳的進(jìn)度拘泞。不同之處在于AFURLSessionManager是針對(duì)所有請(qǐng)求的纷纫,而taskDelegate只是針對(duì)某次具體的請(qǐng)求的。taskDelegate并沒有直接從系統(tǒng)層獲得回調(diào)陪腌,而是所有的回調(diào)都會(huì)先經(jīng)過AFURLSessionManager處理辱魁,然后再分發(fā)給每個(gè)具體的taskDelegate烟瞧,由每個(gè)taskDelegate自己存儲(chǔ)并記錄與當(dāng)前請(qǐng)求相關(guān)的數(shù)據(jù)和信息。至于AFURLSessionManagerTaskDelegate中會(huì)有類似以下的回調(diào)的實(shí)現(xiàn)邏輯:
- (void)URLSession:(__unused NSURLSession *)session
task:(__unused NSURLSessionTask *)task
didSendBodyData:(__unused int64_t)bytesSent
totalBytesSent:(int64_t)totalBytesSent
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{
self.progress.totalUnitCount = totalBytesExpectedToSend;
self.progress.completedUnitCount = totalBytesSent;
}
task的delegate在這里只獲取有用的數(shù)據(jù)染簇,保存了上傳的進(jìn)度参滴,這樣做的目的就是為了保持代碼一致性閱讀起來更容理解,相當(dāng)于代理方法的分發(fā)锻弓。sessionManager里通過字典存下了所有的task砾赔,而又在具體的session回調(diào)中去處理每個(gè)task相關(guān)的邏輯。
AFHTTPSessionManager
它繼承自AFURLSessionManager青灼,主要功能增加了一些初始化的方法以及對(duì)序列化和反序列化階段的錯(cuò)誤檢查暴心,還有設(shè)置具體的序列化對(duì)象。只是在AFURLSessionManager的基礎(chǔ)上做了更容易使用的接口的封裝杂拨。
NSURLSession和NSURLConnection
AFNetworking中NSRULSession的實(shí)現(xiàn)上的設(shè)計(jì)上基本是一致的专普,AFURLSessionManager相當(dāng)于AFHTTPRequestOperationManager。而AFURLConnectionOperation類似與NSURLSessionTask弹沽。但是對(duì)網(wǎng)絡(luò)回調(diào)的實(shí)現(xiàn)上是不一致的檀夹,前者是依賴NSURLSession處理,然后分發(fā)給每個(gè)task自己處理策橘。而NSURLConnection是每個(gè)請(qǐng)求都是獨(dú)立處理各自來自系統(tǒng)層的網(wǎng)絡(luò)回調(diào)炸渡,這是由于采用了不同的系統(tǒng)網(wǎng)絡(luò)框架造成的。兩種實(shí)現(xiàn)都有一個(gè)問題丽已,就是如果baseURL是經(jīng)常變化的蚌堵,下載某一個(gè)素材的時(shí)候,這個(gè)時(shí)候比較好的辦法是只使用NSRULConnection中的AFURLConnectionPeration促脉,每次url由自己指定辰斋,自己去維護(hù)OperationQueue,可能需要自己實(shí)現(xiàn)AFHTTPRequestOperationManager的部分瘸味。