一、文件下載-AFN
示例代碼
- (void)download{
AFHTTPSessionManager *manger = [AFHTTPSessionManager manager];
NSString *url = @"https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=2272971454,2583966854&fm=173&app=25&f=JPEG?w=640&h=621&s=72A22FE3401393E95228E0BA03003047";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
NSURLSessionDownloadTask *loadTask = [manger downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
//下載進度監(jiān)聽
NSLog(@"Progress:----%.2f%",100.0*downloadProgress.completedUnitCount/downloadProgress.totalUnitCount);
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
NSLog(@"fullPath:%@",fullPath);
NSLog(@"targetPath:%@",targetPath);
return [NSURL fileURLWithPath:fullPath];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
NSLog(@"filePath:%@",filePath);
}];
[loadTask resume];
}
二、NSURLConnection
2.1 NSURLConnection下載文件
需要遵行NSURLConnectionDataDelegate
[[NSURLConnection alloc] initWithRequest:request delegate:self]默認是主線程中執(zhí)行,可以設(shè)置代理隊列開啟子線程。注意不能使用主隊列,主隊列會使代理方法失效。
開啟子線程:
[self.urlConnect setDelegateQueue:[[NSOperationQueue alloc]init]];
子線程里創(chuàng)建 NSURLConnection
如果想子線程里創(chuàng)建 NSURLConnection 并設(shè)置代理方法需要如下注意:
1)connectionWithRequest
需要手動開啟子線程的 RunLoop,并且不能占用默認 Model

request
The URL request to load. The request object is deep-copied as part of the initialization process. Changes made to request after this method returns do not affect the request that is used for the loading process.
delegate
The delegate object for the connection. The connection calls methods on this delegate as the load progresses. Delegate methods are called on the same thread that called this method. For the connection to work correctly, the calling thread’s run loop must be operating in the default run loop mode
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSString *url = @"http://xxx.xxx.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
//connectionWithRequest:將NSURLConnection對象作為一個 source 添加到當前 runloop 中,默認運行模式
self.urlConnect = [NSURLConnection connectionWithRequest:request delegate:self];
[self.urlConnect setDelegateQueue:[[NSOperationQueue alloc]init]];
[[NSRunLoop currentRunLoop] run];
});
2)initWithRequest
-
[[NSURLConnection alloc] initWithRequest:request delegate:self];
該方法同上,需要開啟子線程的運行循環(huán)
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSString *url = @"http://xxx.xxx.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
//斷點下載
NSString *bytes = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
[request setValue:bytes forHTTPHeaderField:@"Range"];
self.urlConnect = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[self.urlConnect setDelegateQueue:[[NSOperationQueue alloc]init]];
[[NSRunLoop currentRunLoop] run];
});
-
[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]
可不開啟運行循環(huán),調(diào)用start方法即可。如果 NSURLConnection 對象沒有添加到 RunLoop 中,Start 方法會自動添加到 RunLoop 中,如果當前 RunLoop 沒有開啟,該方法會自動獲取當前線程對應(yīng)的 RunLoop對象并且開啟。
start
- (void)start;
Description
Causes the connection to begin loading data, if it has not already.
Calling this method is necessary only if you create a connection with the initWithRequest:delegate:startImmediately: method and provide NO for the startImmediately parameter. If you don’t schedule the connection in a run loop or an operation queue before calling this method, the connection is scheduled in the current run loop in the default mode.
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSString *url = @"http:// xxx.xxxx.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
//斷點下載
NSString *bytes = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
[request setValue:bytes forHTTPHeaderField:@"Range"];
self.urlConnect = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
[self.urlConnect setDelegateQueue:[[NSOperationQueue alloc]init]];
[self.urlConnect start];
});
文件下載示例代碼
@property (nonatomic, strong) NSString *fullPath;
@property (nonatomic, assign) NSInteger totalSize;
@property (nonatomic, assign) NSInteger currentSize;
@property (nonatomic, strong) NSFileHandle *fileHandle;
- (void)download{
NSString *url = @"http://xxx.xxxx.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
//文件數(shù)據(jù)總大小
self.totalSize = response.expectedContentLength;
//沙盒路徑
self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"123.mp4"];
//空文件
[[NSFileManager defaultManager] createFileAtPath:self.fullPath contents:nil attributes:nil];
//文件句柄
self.fileHandle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
//
//1.文件句柄要在文件最后
[self.fileHandle seekToEndOfFile];
//2.寫數(shù)據(jù)
[self.fileHandle writeData:data];
self.currentSize += data.length;
NSLog(@"%.2f%%",100.0*self.currentSize/self.totalSize);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
//關(guān)閉文件句柄
[self.fileHandle closeFile];
self.fileHandle = nil;
}
2.2 NSURLConnection 斷點續(xù)傳
注意點:
- 設(shè)置請求頭 Range 參數(shù)
- 只創(chuàng)建一次文件路徑、空文件、文件句柄
- 獲取文件請求數(shù)據(jù)大小,并不一定是文件總大小
請求頭參數(shù):
- Range:bytes=x-y 表示請求 從 X 位置起(Y-X+1)個字節(jié)
- Range:bytes=-z 表示請求 最后 Z 個字節(jié)
- Range:bytes=Q- 表示請求Q 字節(jié)以后所有內(nèi)容
示例代碼:
@property (nonatomic, strong) NSString *fullPath;
@property (nonatomic, assign) NSInteger totalSize;
@property (nonatomic, assign) NSInteger currentSize;
@property (nonatomic, strong) NSFileHandle *fileHandle;
@property (nonatomic, strong) NSURLConnection *urlConnect;
- (IBAction)startDownloadBtn:(UIButton *)sender {
[self download];
}
- (IBAction)cancelDownloadBtn:(UIButton *)sender {
[self.urlConnect cancel];
}
修改過代碼:
- (void)download{
NSString *url = @"http://video.yuntoo.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
//斷點下載
NSString *bytes = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
[request setValue:bytes forHTTPHeaderField:@"Range"];
self.urlConnect = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
if (self.currentSize > 0) {
return;
}
//文件請求數(shù)據(jù)大小,期望大小,并不定是總文件大小
self.totalSize = response.expectedContentLength;
//沙盒路徑
self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"123.mp4"];
//空文件
[[NSFileManager defaultManager] createFileAtPath:self.fullPath contents:nil attributes:nil];
//文件句柄
self.fileHandle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
//
//1.文件句柄要在文件最后
[self.fileHandle seekToEndOfFile];
//2.寫數(shù)據(jù)
[self.fileHandle writeData:data];
self.currentSize += data.length;
NSLog(@"%.2f%%",100.0*self.currentSize/self.totalSize);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(@"didFailWithError");
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
//關(guān)閉文件句柄
[self.fileHandle closeFile];
self.fileHandle = nil;
}
三、NSURLSession
使用步驟
-
使用 NSURLSession 創(chuàng)建 task,執(zhí)行 task
task
3.1 GET
2種方法都可以。
dataTaskWithURL 內(nèi)部會自動將請求路徑作為參數(shù)創(chuàng)建一個請求對象,不可變
回調(diào) Block 是在子線程
dataTaskWithRequest 內(nèi)部實現(xiàn)邊接受數(shù)據(jù)變寫入沙盒操作(tmp)
- (void)sessionDownload{
NSString *url = @"http://xxx.xxx.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"completionHandler");
}];
// NSURLSessionDataTask *dataTask = [[session dataTaskWithURL:[NSURL URLWithString:url]] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// NSLog(@"completionHandler");
// }];
[dataTask resume];
}
3.2 POST
NSString *url = @"http://xxx.xxx.com/login";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
request.HTTPMethod = @"POST";
request.HTTPBody = [@"username=123&pwd=d41d8cd98f00b204e9800998ecf8427e" dataUsingEncoding:NSUTF8StringEncoding];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"completionHandler");
}];
// NSURLSessionDataTask *dataTask = [[session dataTaskWithURL:[NSURL URLWithString:url]] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// NSLog(@"completionHandler");
// }];
[dataTask resume];
3.3 代理方法
設(shè)置代理
NSString *url = @"http://img1.dongqiudi.com/fastdfs3/M00/1A/CB/ChOxM1swdjmAGg96AAET60fgKms735.jpg";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
[dataTask resume];
代理方法
//1.接收服務(wù)器的響應(yīng),默認取消該請求
//completionHandler 回調(diào) 傳給系統(tǒng)
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
// NSURLSessionResponseCancel = 0,取消
// NSURLSessionResponseAllow = 1,接收
// NSURLSessionResponseBecomeDownload = 2,下載任務(wù)
// NSURLSessionResponseBecomeStream API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)) = 3,下載任務(wù)
completionHandler(NSURLSessionResponseAllow);
NSLog(@"%s",__func__);
}
//2.收到返回數(shù)據(jù),多次調(diào)用
//拼接存儲數(shù)據(jù)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
NSLog(@"%s",__func__);
}
//3.請求結(jié)束或失敗時調(diào)用
//解析數(shù)據(jù)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
NSLog(@"%s",__func__);
}
3.4 文件下載
3.4.1 簡單方法-downloadTaskWithRequest
無法監(jiān)聽文件下載進度
- (void)sessionDownloadFile{
NSString *url = @"http://img1.dongqiudi.com/fastdfs3/M00/1A/CB/ChOxM1swdjmAGg96AAET60fgKms735.jpg";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
NSLog(@"%@",fullPath);
}];
[dataTask resume];
}
3.4.2 代理下載
遵循NSURLSessionDownloadDelegate
使用NSURLSessionDownloadTask
- (void)sessionDownloadFile2{
NSString *url = @"http://img1.dongqiudi.com/fastdfs3/M00/1A/CB/ChOxM1swdjmAGg96AAET60fgKms735.jpg";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionDownloadTask *dataTask = [session downloadTaskWithRequest:request];
[dataTask resume];
}
代理方法
/**
* 寫數(shù)據(jù)
* @param bytesWritten 本次寫入數(shù)據(jù)大小
* @param totalBytesWritten 下載數(shù)據(jù)總大小
* @param totalBytesExpectedToWrite 文件總大小
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
//1.文件下載進度
NSLog(@"--%.2f%%",100.0*totalBytesWritten/totalBytesExpectedToWrite);
}
/**
* 恢復(fù)下載
* @param fileOffset 恢復(fù)從哪里位置下載
* @param expectedTotalBytes 文件總大小
*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{
}
/**
* 下載完成
* @param location 文件臨時存儲路徑
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
NSLog(@"%@",fullPath);
}
/**
* 請求結(jié)束
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
NSLog(@"didCompleteWithError");
}
3.5 大文件斷點下載-NSURLSessionDownloadTask
注意點:
- 取消下載的方法,
cancel:不可恢復(fù)的;cancelByProducingResumeData:可恢復(fù)的 - 繼續(xù)下載方法需要判斷當前是暫停下載還是取消下載
暫停下載-繼續(xù)下載:是接上次下載
取消下載-繼續(xù)下載:緩存取消下載時resumeData,再進行下載
取消下載-繼續(xù)下載-暫停下載-繼續(xù)下載:緩存取消下載時resumeData-->進行下載-->暫停下載-->是接上次下載
全局變量
@property (nonatomic, strong) NSURLSessionDownloadTask *downloadTask;
@property (nonatomic, strong) NSData *resumeData;
@property (nonatomic, strong) NSURLSession *session;
點擊方法
//開始下載
- (IBAction)startDownloadBtn:(UIButton *)sender {
[self sessionDownloadFile2];
// [self download];
}
//取消下載
- (IBAction)cancelDownloadBtn:(UIButton *)sender {
NSLog(@"-----------------cancelDownloadBtn");
// [self.downloadTask cancel];
//cancel:不可恢復(fù)的
//cancelByProducingResumeData:可恢復(fù)的
//恢復(fù)下載數(shù)據(jù)!= 文件數(shù)據(jù)
[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
self.resumeData = resumeData;
}];
}
//暫停下載
- (IBAction)suspendBtn:(UIButton *)sender {
NSLog(@"-----------------suspendBtn");
[self.downloadTask suspend];
}
//繼續(xù)下載
- (IBAction)goONBtn:(UIButton *)sender {
NSLog(@"-----------------goONBtn");
// NSURLSessionTaskStateRunning = 0,
// NSURLSessionTaskStateSuspended = 1,
// NSURLSessionTaskStateCanceling = 2,
// NSURLSessionTaskStateCompleted = 3,
if (self.downloadTask.state == NSURLSessionTaskStateCompleted) {
if (self.resumeData) {
//resumeData 有值表示取消下載
self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];
}
}
[self.downloadTask resume];
}
NSURLSessionDownloadTask初始化和代理方法
- (void)sessionDownloadFile2{
NSString *url = @"http://video.yuntoo.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionDownloadTask *downloadTask = [self.session downloadTaskWithRequest:request];
[downloadTask resume];
self.downloadTask = downloadTask;
}
/**
* 寫數(shù)據(jù)
* @param bytesWritten 本次寫入數(shù)據(jù)大小
* @param totalBytesWritten 下載數(shù)據(jù)總大小
* @param totalBytesExpectedToWrite 文件總大小
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
//1.文件下載進度
NSLog(@"%.2f%%",100.0 *totalBytesWritten/totalBytesExpectedToWrite);
}
/**
* 恢復(fù)下載
* @param fileOffset 恢復(fù)從哪里位置下載
* @param expectedTotalBytes 文件總大小
*/
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{
}
/**
* 下載完成
* @param location 文件臨時存儲路徑
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
NSLog(@"%@",fullPath);
}
/**
* 請求結(jié)束
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
NSLog(@"didCompleteWithError");
}
3.6 大文件離線斷點下載-NSURLSessionDataTask
遵循NSURLSessionDataDelegate
使用NSURLSessionDataTask
- 斷點下載是從內(nèi)存中取出當前下載數(shù)據(jù)的
Size,然后設(shè)置請求頭的Range - 離線斷點下載是從沙盒中取出已下載的數(shù)據(jù)的
Size,然后設(shè)置請求頭的Range
全局變量
@property (nonatomic, strong) NSString *fullPath;
@property (nonatomic, assign) NSInteger totalSize;
@property (nonatomic, assign) NSInteger currentSize;
@property (nonatomic, strong) NSFileHandle *fileHandle;
@property (nonatomic, strong) NSURLSessionDataTask *dataTask;
-(NSString *)fullPath{
if (_fullPath == nil) {
_fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"1234.mp4"];
}
return _fullPath;
}
初始化NSURLSessionDataTask
- 從沙盒緩存中取已下載文件的大小
- 設(shè)置NSMutableURLRequest 的斷點下載范圍
Range
-(NSURLSessionDataTask *)dataTask{
if (_dataTask == nil) {
NSString *url = @"http://xxx.xxxx.com/dist/ab7b54f3-8df0-4678-babc-15a6e4f642b7.mp4";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
NSDictionary *fileDict = [[NSFileManager defaultManager] attributesOfItemAtPath:self.fullPath error:nil];
self.currentSize = [[fileDict valueForKey:@"NSFileSize"] integerValue];
NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
[request setValue:range forHTTPHeaderField:@"Range"];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
_dataTask = [session dataTaskWithRequest:request];
}
return _dataTask;
}
開始、取消、繼續(xù)、暫停方法
//開始下載
- (IBAction)startDownloadBtn:(UIButton *)sender {
NSLog(@"-----------------startDownloadBtn");
[self.dataTask resume];
}
//取消下載
- (IBAction)cancelDownloadBtn:(UIButton *)sender {
NSLog(@"-----------------cancelDownloadBtn");
[self.dataTask cancel];
self.dataTask = nil;
}
//暫停下載
- (IBAction)suspendBtn:(UIButton *)sender {
NSLog(@"-----------------suspendBtn");
[self.dataTask suspend];
}
//繼續(xù)下載
- (IBAction)goONBtn:(UIButton *)sender {
NSLog(@"-----------------goONBtn");
[self.dataTask resume];
}
代理方法
//1.接收服務(wù)器的響應(yīng),默認取消該請求
//completionHandler 回調(diào) 傳給系統(tǒng)
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
// NSURLSessionResponseCancel = 0,取消
// NSURLSessionResponseAllow = 1,接收
// NSURLSessionResponseBecomeDownload = 2,下載任務(wù)
// NSURLSessionResponseBecomeStream API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0),
if (self.currentSize == 0) {
[[NSFileManager defaultManager] createFileAtPath:self.fullPath contents:nil attributes:nil];
}
self.fileHandle = [NSFileHandle fileHandleForWritingAtPath:_fullPath];
self.totalSize = response.expectedContentLength+self.currentSize;
completionHandler(NSURLSessionResponseAllow);
}
//2.收到返回數(shù)據(jù),多次調(diào)用
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
[self.fileHandle seekToEndOfFile];
[self.fileHandle writeData:data];
self.currentSize += data.length;
NSLog(@"%.2f",100.0* self.currentSize / self.totalSize);
}
//3.請求結(jié)束或失敗時調(diào)用
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
[self.fileHandle closeFile];
self.fileHandle = nil;
NSLog(@"didCompleteWithError:%@",_fullPath);
}
Session 釋放
-(void)dealloc{
[self.session invalidateAndCancel];
}
其他
輸出流
保存數(shù)據(jù)
初始化
//輸出流指向地址沒有文件會新建文件
self.outStream = [[NSOutputStream alloc] initToFileAtPath:self.fullPath append:YES];
[self.outStream open];
寫數(shù)據(jù)
[self.outStream write:data.bytes maxLength:data.length];
關(guān)閉
[self.outStream close];

