1 基本說明
記得我剛做iOS的時候,那時候還是ASI和AFN共存,甚至ASI使用比例還多點,一轉(zhuǎn)眼幾年過去,ASI基本已經(jīng)消失了,AFN基本成了iOS項目的標(biāo)配。我雖然以前也有看過AFN2.x的源碼,但是對于AFN3.x的源碼一直沒有自己閱讀。接下來我會對AFN3.x學(xué)習(xí)并且寫博客記錄。得益于NSURLSession的強(qiáng)大功能,ANF3.0放棄了NSURLConnection這一部分,讓代碼簡化了很多,但是功能卻更加豐富。我覺得在學(xué)習(xí)AFN之前,有必要仔細(xì)了解NSURLSession和https相關(guān),不然會有很多地方迷惑不解,具體可以看我的git倉庫iOSSourceCodeStudy
。同時我強(qiáng)烈推薦瀏覽一下NSURLSession.h這個文件。
2 相互關(guān)系
我們首先來看一下一個簡單的NSURLSession請求代碼:
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:bigPic]];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
[dataTask resume];
從上面我們發(fā)現(xiàn),我們要發(fā)送一個網(wǎng)絡(luò)請求,需要新建一個NSURLSession,新建一個NSURLSession又需要一個NSURLSessionConfiguration,并且還需要一些代理方法。同時我們需要一個NSURLSessionDataTask。所以說,我們的NSRULSession
網(wǎng)絡(luò)請求系統(tǒng)包括一個session、一個configuration、一個Task已經(jīng)Task附帶的delegate。
- 一個
NSURLSession,總共只有一個類,也是最核心的類,他有一個對應(yīng)的代理NSURLSessionDelegate。 - 一個
NSURLSessionConfiguration,總共有三種模式。 - 一個
NSURLSessionTask。NSURLSessionTask是抽閑類,對應(yīng)的代理NSURLSessionTaskDelegate。我們具體使用的時候,會使用他的三種子類,而且每個子類都有對應(yīng)的delegate。
3 一個NSURLSession
首先我們看一下NSRULSession.h里面關(guān)于NSURLSession的部分。我們把它分為初始化部分、屬性部分、dataTask部分、uploadTask部分、downloadTask部分。也就是說其他很多類都是圍繞著下面這幾個api衍生的。后面我們會每個部分分析。
//初始化部分
@property (class, readonly, strong) NSURLSession *sharedSession;
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
//屬性部分
@property (readonly, retain) NSOperationQueue *delegateQueue;
@property (nullable, readonly, retain) id <NSURLSessionDelegate> delegate;
@property (readonly, copy) NSURLSessionConfiguration *configuration;
//dataTask部分
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;
//uploadTask部分
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData;
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request;
//downloadTask部分
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url;
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;
3.1 Block的NSURLSession的api
我們都知道,NSRULConnection除了一套使用代理的API,還有一套對應(yīng)的使用Block的api。NSURLSession也不列外。使用這一套api就不用實現(xiàn)代理方法。和delegate一樣,Block也有dataTask系列、downloadTask系列、uploadTask系列。具體看下面:
//dataTask系列
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler{
}
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler{
}
//unloadTast系列
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler{
}
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(nullable NSData *)bodyData completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler{
}
//downloadTask系列
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler{
}
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler{
}
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler{
}
3.2 Block的NSURLSession使用
用dataTask下載一張圖片,然后用imageView顯示。
-(IBAction)requestBlockTaskTest:(id)sender{
[self clear];
NSURLSession *session = [NSURLSession sharedSession];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:bigPic]];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
UIImage *image = [[UIImage alloc]initWithData:data];
self.imageView.image = image;
}];
[dataTask resume];
}
4 一個NSURLSessionConfiguration
首先看一下NSURLSessionConfiguration部分。從這個名字,我們可以預(yù)感到這個是與session的配置相關(guān)的,的確也是這樣??偣灿腥N類型的configuratin,另外還有很多屬性,比如配置緩存策略的requestCachePolicy,請求超時的timeoutIntervalForRequest,添加額外請求頭的HTTPAdditionalHeaders,其他還有很多屬性這里就不一一說了,具體看源碼:
//默認(rèn)的配置會將緩存存儲在磁盤上
@property (class, readonly, strong) NSURLSessionConfiguration *defaultSessionConfiguration;
//第二種瞬時會話模式不會創(chuàng)建持久性存儲的緩存.
@property (class, readonly, strong) NSURLSessionConfiguration *ephemeralSessionConfiguration;
//第三種后臺會話模式允許程序在后臺進(jìn)行上傳下載工作
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier;
//各種屬性
@property NSURLRequestCachePolicy requestCachePolicy;
@property NSTimeInterval timeoutIntervalForRequest;
@property (nullable, copy) NSDictionary *HTTPAdditionalHeaders;
5 一個NSURLSessionTask
從上面NSURLSession初始化一個請求的時候,我們發(fā)現(xiàn)NSURLSessionTask并不能直接使用,只能使用他的子類。具體如下:
-
NSURLSessionTask抽象類。有對應(yīng)的代理NSURLSessionTaskDelegate,而且這個代理繼承了NSURLSessionDelegate代理。 -
NSURLSessionDataTask是NSURLSessionTask的子類。有對應(yīng)的代理NSURLSessionTaskDelegate,而且這個代理繼承了NSURLSessionTaskDelegate代理。我們一般網(wǎng)絡(luò)請求,就用這個類。 -
NSURLSessionDownloadTask是NSURLSessionTask的子類。有對應(yīng)的代理NSURLSessionDownloadDelegate,而且這個代理繼承了NSURLSessionTaskDelegate代理。這個主要用于下載大文件等。 -
NSURLSessionUploadTask是NSURLSessionDataTask的子類。有對應(yīng)的代理及時父類代理NSURLSessionDownloadDelegate。這個主要用于處理上傳請求如上傳圖片。
從上面我們發(fā)現(xiàn)Task和delegate有一套對應(yīng)的繼承關(guān)系:
-
NSURLSessionTask (抽象類,
NSURLSessionTaskDelegate)- NSURLSessionDataTask (
NSURLSessionDataDelegate)- NSURLSessionUploadTask (
NSURLSessionDataDelegate)
- NSURLSessionUploadTask (
- NSURLSessionDownloadTask (
NSURLSessionDownloadDelegate)
- NSURLSessionDataTask (
-
NSURLSessionDelegate
- NSURLSessionTaskDelegate
- NSURLSessionDataDelegate
- NSURLSessionDownloadDelegate
- NSURLSessionTaskDelegate
從繼承關(guān)系上,我們就可以理解在初始化的時候,只通過設(shè)置NSURLSession對象的delegate就可以了。因為根據(jù)不同的task,其實就是設(shè)置了不同的delegate。這個設(shè)計避免了多次設(shè)置delegate的情況,同時也根據(jù)不同的task實現(xiàn)不同的delegate方法。真是一個很絕妙的設(shè)計。
6 代理說明
6.1 NSURLSessionDelegate
接下來我們看看NSURLSession的delegate對象NSURLSessionDelegate的方法,當(dāng)一個session遇到錯誤、或者需要認(rèn)證、應(yīng)用進(jìn)入后臺都會調(diào)用下面的代理方法:
//當(dāng)一個session遇到系統(tǒng)錯誤或者未檢測到的錯誤的時候,就會調(diào)用這個方法。
- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error{
}
//當(dāng)請求需要認(rèn)證、或者h(yuǎn)ttps證書認(rèn)證的時候,我們就需要在這個方法里面處理。
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
}
//如果應(yīng)用進(jìn)入后臺、這個方法會被調(diào)用。我們在這里可以對session發(fā)起的請求做各種操作比如請求完成的回調(diào)等。
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
}
6.2 NSURLSessionTaskDelegate
/*
當(dāng)請求重定向的時候調(diào)用這個方法。我們必須設(shè)置一個新的`NSURLRequest`對象傳入completionHandler來重定向新的請求,但是當(dāng)`session`是background模式的時候,這個方法不會被調(diào)用。
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
willPerformHTTPRedirection:(NSHTTPURLResponse *)response
newRequest:(NSURLRequest *)request
completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler{
}
/*
當(dāng)請求需要認(rèn)證的時候調(diào)用這個方法。如果沒有實現(xiàn)這個代理,那么請求認(rèn)證這個過程不會被調(diào)用。
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
}
/*
如果請求需要一個新的請求體時,這個方法就會被調(diào)用。比如認(rèn)證失敗的時候,我們可以通過這個機(jī)會從新認(rèn)證。
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
needNewBodyStream:(void (^)(NSInputStream * _Nullable bodyStream))completionHandler{
}
/*
當(dāng)我們上傳數(shù)據(jù)的時候,我們可以通過這個代理方法獲取上傳進(jìn)度。
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didSendBodyData:(int64_t)bytesSent
totalBytesSent:(int64_t)totalBytesSent
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend{
}
/*
當(dāng)task的統(tǒng)計信息收集好了以后,調(diào)用這個方法。
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics {
}
/*
當(dāng)一個task出錯的時候,會調(diào)用這個方法。如果error是nil,也會調(diào)用這個方法,表示task完成。
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(nullable NSError *)error{
NSLog(@"數(shù)據(jù)返回以后,不管有錯沒錯都回調(diào)用,如果沒錯,error及時nil");
}
6.3 NSURLSessionDataDelegate
/*
當(dāng)一個task接收到返回信息。當(dāng)所有信息都接收完畢以后,completionHandler會被調(diào)用。我們可以在這里取消一個網(wǎng)絡(luò)請求或者把一個datatask轉(zhuǎn)換為downloadtask。如果沒有實現(xiàn)這個代理方法,我們也可以通過task的response屬性獲取到對應(yīng)的數(shù)據(jù)。background模式的uploadtask不會調(diào)用這個方法。
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler{
}
/*
當(dāng)一個datatask轉(zhuǎn)換為一個downloadtask以后會調(diào)用。
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask{
// 允許處理服務(wù)器的響應(yīng),才會繼續(xù)接收服務(wù)器返回的數(shù)據(jù)
completionHandler(NSURLSessionResponseAllow);
}
/*
暫時忽略,這個是和數(shù)據(jù)流相關(guān)的。不管了
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didBecomeStreamTask:(NSURLSessionStreamTask *)streamTask{
}
/*
當(dāng)data可以使用的時候,調(diào)用這個方法。我們可以在這里獲取data。
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data{
}
/*
允許我們在這里調(diào)用completionHandler緩存data,或者傳入nil來禁止緩存
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
willCacheResponse:(NSCachedURLResponse *)proposedResponse
completionHandler:(void (^)(NSCachedURLResponse * _Nullable cachedResponse))completionHandler{
}
6.4 NSURLSessionDownloadDelegate
/*
當(dāng)一個下載task任務(wù)完成以后,這個方法會被調(diào)用。我們可以在這里移動或者復(fù)制download的數(shù)據(jù)
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location{
}
/*
獲取下載進(jìn)度
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didWriteData:(int64_t)bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
}
/*
重啟一個下載任務(wù)(比如下載一半后停止然后過一點時間繼續(xù))。如果下載出錯,`NSURLSessionDownloadTaskResumeData`里面包含重新開始下載的數(shù)據(jù)。
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didResumeAtOffset:(int64_t)fileOffset
expectedTotalBytes:(int64_t)expectedTotalBytes{
}
7 NSURLSession的綜合使用案列
分別用三種不同方式下載一張圖片然后在imageView上顯示。
#import "ViewController.h"
static NSString *const bigPic = @"http://i1.piimg.com/4851/d1498fea89ae3bc1.png";
static NSString *const smallPic = @"http://i1.piimg.com/4851/97aef4680d359905.png";
@interface ViewController ()<NSURLSessionDelegate>
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property(nonatomic,strong)NSMutableData *data;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)requestDataTest:(id)sender {
[self clear];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:bigPic]];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
[dataTask resume];
}
- (IBAction)requestDownloadTest:(id)sender {
[self clear];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:bigPic]];
NSURLSessionDownloadTask *dataTask = [session downloadTaskWithRequest:request];
[dataTask resume];
}
-(IBAction)requestBlockTaskTest:(id)sender{
[self clear];
NSURLSession *session = [NSURLSession sharedSession];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:bigPic]];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
UIImage *image = [[UIImage alloc]initWithData:data];
self.imageView.image = image;
}];
[dataTask resume];
}
-(void)clear{
self.imageView.image = nil;
}
//==============================NSURLSessionDelegate========================
#pragma NSURLSessionDelegate
//當(dāng)一個session遇到系統(tǒng)錯誤或者未檢測到的錯誤的時候,就會調(diào)用這個方法。
- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error{
}
//當(dāng)請求需要認(rèn)證、或者h(yuǎn)ttps證書認(rèn)證的時候,我們就需要在這個方法里面處理。
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
}
//如果應(yīng)用進(jìn)入后臺、這個方法會被調(diào)用。我們在這里可以對session發(fā)起的請求做各種操作比如請求完成的回調(diào)等。
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
}
//==================================NSURLSessionTaskDelegate====================
#pragma NSURLSessionTaskDelegate
/*
當(dāng)請求重定向的時候調(diào)用這個方法。我們必須設(shè)置一個新的`NSURLRequest`對象傳入completionHandler來重定向新的請求,但是當(dāng)`session`是background模式的時候,這個方法不會被調(diào)用。
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
willPerformHTTPRedirection:(NSHTTPURLResponse *)response
newRequest:(NSURLRequest *)request
completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler{
}
/*
當(dāng)請求需要認(rèn)證的時候調(diào)用這個方法。如果沒有實現(xiàn)這個代理,那么請求認(rèn)證這個過程不會被調(diào)用。
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
}
/*
如果請求需要一個新的請求體時,這個方法就會被調(diào)用。比如認(rèn)證失敗的時候,我們可以通過這個機(jī)會從新認(rèn)證。
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
needNewBodyStream:(void (^)(NSInputStream * _Nullable bodyStream))completionHandler{
}
/*
當(dāng)我們上傳數(shù)據(jù)的時候,我們可以通過這個代理方法獲取上傳進(jìn)度。
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didSendBodyData:(int64_t)bytesSent
totalBytesSent:(int64_t)totalBytesSent
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend{
NSLog(@"");
}
/*
當(dāng)task的統(tǒng)計信息收集好了以后,調(diào)用這個方法。
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics {
}
/*
當(dāng)一個task出錯的時候,會調(diào)用這個方法。如果error是nil,也會調(diào)用這個方法,表示task完成。
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(nullable NSError *)error{
NSLog(@"數(shù)據(jù)返回以后,不管有錯沒錯都回調(diào)用,如果沒錯,error及時nil");
if (self.data) {
self.imageView.image = [UIImage imageWithData:self.data];
self.data = nil;
}
}
//==================================NSURLSessionDataDelegate=====================================
#pragma NSURLSessionDataDelegate
/*
當(dāng)一個task接收到返回信息。當(dāng)所有信息都接收完畢以后,completionHandler會被調(diào)用。我們可以在這里取消一個網(wǎng)絡(luò)請求或者把一個datatask轉(zhuǎn)換為downloadtask。如果沒有實現(xiàn)這個代理方法,我們也可以通過task的response屬性獲取到對應(yīng)的數(shù)據(jù)。background模式的uploadtask不會調(diào)用這個方法。
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler{
self.data = nil;
self.data = [NSMutableData data];
// 允許處理服務(wù)器的響應(yīng),才會繼續(xù)接收服務(wù)器返回的數(shù)據(jù)
completionHandler(NSURLSessionResponseAllow);
}
/*
當(dāng)一個datatask轉(zhuǎn)換為一個downloadtask以后會調(diào)用。
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask{
}
/*
暫時忽略,這個是和數(shù)據(jù)流相關(guān)的。不管了
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didBecomeStreamTask:(NSURLSessionStreamTask *)streamTask{
}
/*
當(dāng)data可以使用的時候,調(diào)用這個方法。我們可以在這里獲取data。
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data{
[self.data appendData:data];
NSLog(@"具體數(shù)據(jù)在URLSession:(NSURLSession *)session task:(NSURLSessionTask *)taskdidCompleteWithError:(nullable NSError *)error處理");
}
/*
允許我們在這里調(diào)用completionHandler緩存data,或者傳入nil來禁止緩存
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
willCacheResponse:(NSCachedURLResponse *)proposedResponse
completionHandler:(void (^)(NSCachedURLResponse * _Nullable cachedResponse))completionHandler{
}
//==================================NSURLSessionDownloadTask=================================
#pragma NSURLSessionDownloadTask
/*
當(dāng)一個下載task任務(wù)完成以后,這個方法會被調(diào)用。我們可以在這里移動或者復(fù)制download的數(shù)據(jù)
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location{
NSString *path = location.absoluteString;
UIImage *image = [[UIImage alloc]initWithData:[NSData dataWithContentsOfURL:location]];
self.imageView.image = image;
NSLog(@"數(shù)據(jù)下載完成以后,會保存在一個location的地方。%@",location);
}
/*
獲取下載進(jìn)度
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didWriteData:(int64_t)bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
NSLog(@"總得數(shù)據(jù)大小%lld----",bytesWritten);
}
/*
重啟一個下載任務(wù)(比如下載一半后停止然后過一點時間繼續(xù))。如果下載出錯,`NSURLSessionDownloadTaskResumeData`里面包含重新開始下載的數(shù)據(jù)。
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didResumeAtOffset:(int64_t)fileOffset
expectedTotalBytes:(int64_t)expectedTotalBytes{
}
@end