需求:1、下載大文件
2、取消下載,和暫停下載,繼續(xù)下載
3、顯示下載進(jìn)度
1、第一種方式基于:NSURLConnection(備注:該方法在iOS9已經(jīng)被棄用了)
a、首先聲明需要用得變量
@property (nonatomic,strong) NSFileHandle *fileHandle; // 文件句柄
@property (nonatomic,assign) long long totalFileLength; // 記錄下載
@property (nonatomic,assign) long long currentFileLength; // 已經(jīng)下載好的長度
@property (nonatomic,strong) NSURLConnection *connection;
b、在下載按鈕中實(shí)現(xiàn)下載和取消下載(記得遵守NSURLConnectionDataDelegate協(xié)議)
- (IBAction)downAction:(UIButton *)sender {
sender.selected = !sender.selected;
if (sender.selected) {
//下載
NSString *urlString = @"youdwonloadpath"; // 下載路徑
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
//設(shè)置請(qǐng)求頭下載范圍從哪里開始(很重要)
NSString *range = [NSString stringWithFormat:@"bytes=%lld",self.currentFileLength];
[request setValue:range forHTTPHeaderField:@"Range"];
// 發(fā)起異步下載請(qǐng)求
self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
else {
//取消下載
[self.connection cancel];
}
}
c、NSURLConnectionDataDelegate方法
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
if (self.currentFileLength) {
return;
} // 如果已經(jīng)下載了,就不要再創(chuàng)建文件夾了
// 開始響應(yīng)
//1、首先獲取文件的長度
self.totalFileLength = response.expectedContentLength;
// 創(chuàng)建一個(gè)空的文件
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingString:@"video.zip"];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager createFileAtPath:filePath contents:nil attributes:nil];
// 創(chuàng)建一個(gè)文件句柄
self.fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// 接受數(shù)據(jù)
self.currentFileLength+=data.length;
float progress = (double)self.currentFileLength/self.totalFileLength;
NSLog(@"%f",progress);
//文件最后面
[self.fileHandle seekToEndOfFile];
// 把數(shù)據(jù)拼接到文件最后面
[self.fileHandle writeData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// 下載完成
self.currentFileLength = 0;
self.totalFileLength = 0;
// 一定要關(guān)閉
[self.fileHandle closeFile];
self.fileHandle = nil;
}
2、第二種方式基于:NSURLSession的大文件下載(備注:該方法iOS7才推出,蘋果推薦)
a、遵守協(xié)議NSURLSessionDownloadDelegate,NSURLSessionDataDelegate
申明變量
/**
* 下載任務(wù)
*/
@property(nonatomic, strong) NSURLSessionDownloadTask *downLoadTask;
@property(nonatomic, strong) NSURLSession *session;
@property(nonatomic, strong) NSData *resumeData; // 暫停下載返回的數(shù)據(jù)
b、下載按鈕中實(shí)現(xiàn)
- (IBAction)downLoadAction:(UIButton *)sender {
sender.selected = !sender.selected;
if (sender.selected) {
if (self.resumeData) {
[self resumeDownLoad];
}
else {
[self startDownLoad];
}
}
else {
[self pauseDownLoad];
}
}
幾個(gè)方法的實(shí)現(xiàn)
// 開始下載
- (void)startDownLoad {
NSString *urlString = @"youdownloadpath"; // 下載路徑
// 創(chuàng)建下載任務(wù)
self.downLoadTask = [self.session downloadTaskWithURL:[NSURL URLWithString:urlString]];
// 開始下載任務(wù)
[self.downLoadTask resume];
}
// 恢復(fù)下載
- (void)resumeDownLoad {
// 傳入上次暫停下載返回的數(shù)據(jù),就可以恢復(fù)下載
self.downLoadTask = [self.session downloadTaskWithResumeData:self.resumeData];
[self.downLoadTask resume];
// 記得請(qǐng)空resumeData
self.resumeData = nil;
}
// 暫停下載
- (void)pauseDownLoad {
//取消任務(wù)
__weak typeof(self) weakSelf = self;
[self.downLoadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
weakSelf.resumeData = resumeData;
//記得清空任務(wù)
weakSelf.downLoadTask = nil;
}];
}
c、代理方法中的實(shí)現(xiàn)(重要)
// 恢復(fù)下載時(shí)調(diào)用
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes {
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
// 在這里顯示進(jìn)度條
self.progressView.progress = (double)totalBytesWritten/totalBytesExpectedToWrite;
}
// 下載完成后調(diào)用
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [cachesPath stringByAppendingString:downloadTask.response.suggestedFilename];
//剪切文件到指定的路徑
NSFileManager *manager = [NSFileManager defaultManager];
[manager moveItemAtPath:location.path toPath:filePath error:nil];
}
總結(jié):
個(gè)人認(rèn)為NSURLSession使用簡單一點(diǎn),不用設(shè)置請(qǐng)求頭啊,也不要自己拼接數(shù)據(jù)存儲(chǔ),畢竟蘋果推薦