版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2018.02.28 |
前言
我們做APP發(fā)起網(wǎng)絡(luò)請(qǐng)求翰苫,都離不開一個(gè)非常有用的框架AFNetworking育拨,可以說這個(gè)框架的知名度已經(jīng)超過了蘋果的底層網(wǎng)絡(luò)請(qǐng)求部分谨履,很多人可能不知道蘋果底層是如何發(fā)起網(wǎng)絡(luò)請(qǐng)求的,但是一定知道
AFNetworking
熬丧,接下來幾篇我們就一起詳細(xì)的解析一下這個(gè)框架笋粟。感興趣的可以看上面寫的幾篇。
1. AFNetworking源碼探究(一) —— 基本介紹
2. AFNetworking源碼探究(二) —— GET請(qǐng)求實(shí)現(xiàn)之NSURLSessionDataTask實(shí)例化(一)
3. AFNetworking源碼探究(三) —— GET請(qǐng)求實(shí)現(xiàn)之任務(wù)進(jìn)度設(shè)置和通知監(jiān)聽(一)
4. AFNetworking源碼探究(四) —— GET請(qǐng)求實(shí)現(xiàn)之代理轉(zhuǎn)發(fā)思想(一)
5. AFNetworking源碼探究(五) —— AFURLSessionManager中NSURLSessionDelegate詳細(xì)解析(一)
6. AFNetworking源碼探究(六) —— AFURLSessionManager中NSURLSessionTaskDelegate詳細(xì)解析(一)
回顧
上一篇主要介紹了NSURLSessionTaskDelegate
中五個(gè)代理方法的實(shí)現(xiàn)及其使用場(chǎng)景和注意事項(xiàng)析蝴。這一篇主要介紹NSURLSessionDataDelegate
幾個(gè)代理方法害捕。
1. - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler;
首先看一下蘋果該方法的API
/* The task has received a response and no further messages will be
* received until the completion block is called. The disposition
* allows you to cancel a request or to turn a data task into a
* download task. This delegate message is optional - if you do not
* implement it, you can get the response as a property of the task.
*
* This method will not be called for background upload tasks (which cannot be converted to download tasks).
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler;
看一下AFN中該方法的實(shí)現(xiàn)
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
{
NSURLSessionResponseDisposition disposition = NSURLSessionResponseAllow;
if (self.dataTaskDidReceiveResponse) {
disposition = self.dataTaskDidReceiveResponse(session, dataTask, response);
}
if (completionHandler) {
completionHandler(disposition);
}
}
這里,NSURLSessionResponseDisposition disposition = NSURLSessionResponseAllow;
表示默認(rèn)為繼續(xù)進(jìn)行嫌变。
-
completionHandler
這個(gè)block吨艇,通過傳入一個(gè)類型為NSURLSessionResponseDisposition
的變量來決定該傳輸任務(wù)接下來該做什么:-
NSURLSessionResponseAllow
該task正常進(jìn)行 -
NSURLSessionResponseCancel
該task會(huì)被取消 -
NSURLSessionResponseBecomeDownload
會(huì)調(diào)用URLSession:dataTask:didBecomeDownloadTask:
方法來新建一個(gè)download task
以代替當(dāng)前的data task
-
NSURLSessionResponseBecomeStream
轉(zhuǎn)成一個(gè)StreamTask
-
當(dāng)你把添加
content-type
的類型為multipart/x-mixed-replace
那么服務(wù)器的數(shù)據(jù)會(huì)分片的傳回來。然后這個(gè)方法是每次接受到對(duì)應(yīng)片響應(yīng)的時(shí)候會(huì)調(diào)被調(diào)用腾啥。你應(yīng)該在這個(gè)函數(shù)中合理地處理先前的數(shù)據(jù)东涡,否則會(huì)被新數(shù)據(jù)覆蓋。
2. - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask;
首先看一下蘋果該方法的API
/* Notification that a data task has become a download task. No
* future messages will be sent to the data task.
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask;
看一下AFN中該方法的實(shí)現(xiàn)
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask
{
AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:dataTask];
if (delegate) {
[self removeDelegateForTask:dataTask];
[self setDelegate:delegate forTask:downloadTask];
}
if (self.dataTaskDidBecomeDownloadTask) {
self.dataTaskDidBecomeDownloadTask(session, dataTask, downloadTask);
}
}
當(dāng)代理1方法中的disposition = NSURLSessionResponseBecomeDownload
的時(shí)候倘待,就會(huì)調(diào)用這個(gè)方法疮跑。
這個(gè)代理方法是被上面的代理方法觸發(fā)的,作用就是新建一個(gè)downloadTask
凸舵,替換掉當(dāng)前的dataTask
祖娘。所以我們?cè)谶@里做了AF自定義代理的重新綁定操作[self setDelegate:delegate forTask:downloadTask];
。
3. - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
首先看一下蘋果該方法的API
/* Sent when data is available for the delegate to consume. It is
* assumed that the delegate will retain and not copy the data. As
* the data may be discontiguous, you should use
* [NSData enumerateByteRangesUsingBlock:] to access it.
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data;
看一下AFN中該方法的實(shí)現(xiàn)
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data
{
AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:dataTask];
[delegate URLSession:session dataTask:dataTask didReceiveData:data];
if (self.dataTaskDidReceiveData) {
self.dataTaskDidReceiveData(session, dataTask, data);
}
}
- 獲取到數(shù)據(jù)就會(huì)調(diào)用啊奄,會(huì)被反復(fù)調(diào)用渐苏,請(qǐng)求到的數(shù)據(jù)就在這被拼裝完整。
- 這個(gè)方法和上面
didCompleteWithError
算是NSURLSession
的代理中最重要的兩個(gè)方法菇夸。 - 我們轉(zhuǎn)發(fā)了這個(gè)方法到AF的代理中去琼富,所以數(shù)據(jù)的拼接都是在AF的代理中進(jìn)行的。這也是情理中的庄新,畢竟每個(gè)響應(yīng)數(shù)據(jù)都是對(duì)應(yīng)各個(gè)task鞠眉,各個(gè)AF代理的薯鼠。在
AFURLSessionManager
都只是做一些公共的處理。
4. - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask willCacheResponse:(NSCachedURLResponse *)proposedResponse completionHandler:(void (^)(NSCachedURLResponse * _Nullable cachedResponse))completionHandler;
首先看一下蘋果該方法的API
/* Invoke the completion routine with a valid NSCachedURLResponse to
* allow the resulting data to be cached, or pass nil to prevent
* caching. Note that there is no guarantee that caching will be
* attempted for a given resource, and you should not rely on this
* message to receive the resource data.
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
willCacheResponse:(NSCachedURLResponse *)proposedResponse
completionHandler:(void (^)(NSCachedURLResponse * _Nullable cachedResponse))completionHandler;
看一下AFN中該方法的實(shí)現(xiàn)
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
willCacheResponse:(NSCachedURLResponse *)proposedResponse
completionHandler:(void (^)(NSCachedURLResponse *cachedResponse))completionHandler
{
NSCachedURLResponse *cachedResponse = proposedResponse;
if (self.dataTaskWillCacheResponse) {
cachedResponse = self.dataTaskWillCacheResponse(session, dataTask, proposedResponse);
}
if (completionHandler) {
completionHandler(cachedResponse);
}
}
- 該方法的作用就是詢問data task或上傳任務(wù)(upload task)是否緩存response械蹋。
- 當(dāng)task接收到所有期望的數(shù)據(jù)后出皇,session會(huì)調(diào)用此代理方法。
- 當(dāng)task接收到所有期望的數(shù)據(jù)后哗戈,session會(huì)調(diào)用此代理方法郊艘。如果你沒有實(shí)現(xiàn)該方法,那么就會(huì)使用創(chuàng)建session時(shí)使用的configuration對(duì)象決定緩存策略唯咬。這個(gè)代理方法最初的目的是為了阻止緩存特定的URLs或者修改
NSCacheURLResponse
對(duì)象相關(guān)的userInfo
字典暇仲。 - 該方法只會(huì)當(dāng)
request
決定緩存response
時(shí)候調(diào)用。作為準(zhǔn)則副渴,responses只會(huì)當(dāng)以下條件都成立的時(shí)候返回緩存:- 該request是HTTP或HTTPS URL的請(qǐng)求(或者你自定義的網(wǎng)絡(luò)協(xié)議奈附,并且確保該協(xié)議支持緩存)
- 確保request請(qǐng)求是成功的(返回的status code為200-299)
- 返回的response是來自服務(wù)器端的,而非緩存中本身就有的
- 提供的
NSURLRequest
對(duì)象的緩存策略要允許進(jìn)行緩存 - 服務(wù)器返回的response中與緩存相關(guān)的header要允許緩存
- 該response的大小不能比提供的緩存空間大太多(比如你提供了一個(gè)磁盤緩存煮剧,那么response大小一定不能比磁盤緩存空間還要大5%)
后記
本篇主要介紹了NSURLSessionDataDelegate中四個(gè)代理方法的實(shí)現(xiàn)及其使用場(chǎng)景和注意事項(xiàng)斥滤。