初始化下載管理器
1弛槐、遍歷正下載Plist的所有字典成模型數(shù)組
2章蚣、給所有下載模型賦值Task
3、計算所有模型的已下載大小
4摆马、將模型數(shù)組賦值給下載管理器的臨時數(shù)組
添加下載
1、判斷當(dāng)前url文件的下載狀態(tài)(已下載棕孙、正下載丸逸、未下載)
2、
下載數(shù)據(jù)管理
1猛蔽、臨時下載信息路徑
/Library/Caches/DownLoad/CacheList/自行車.mp4.plist
2、下載完成文件路徑
/Library/Caches/DownLoad/LocalList/自行車.mp4
3灵寺、FinishedPlist.plist
[self.filelist addObject:_fileInfo];
4曼库、臨時.plist文件Path->下載信息Model
5、計算已下載文件的大小略板,方便繼續(xù)斷點下載
創(chuàng)建請求
-
Get
// NSURL
NSURL *url = [NSURL URLWithString:@""];
// NSURLRequest
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// NSURLSession
NSURLSession *session = [NSURLSession sessionWithConfiguartion:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOpertationQueue alloc] init]];
// NSURLSessionDataTask
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"%@", [NSJSONSerialazation JSONObjectWithData:data options:kNilOptions error:nil]);
}];
[task resume];
-
Post
-
Delegate
#pragma mark --------------------------------------- <NSURLSessionDataDelegate>
/**
* 服務(wù)器開始響應(yīng)
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
// url標識符->請求模型
JHDownloadInfo *info = [self downloadInfoForURL:dataTask.taskDescription];
// 請求模型->準備開始
[info didReceiveResponse:response];
// 更新本地Plist表
[self addToLocalPlist:info];
// 回調(diào)開始下載
if([self.downloadDelegate respondsToSelector:@selector(startDownload:)]) {
[self.downloadDelegate startDownload:info];
}
// 繼續(xù)
completionHandler(NSURLSessionResponseAllow);
}
/**
* 服務(wù)器發(fā)送數(shù)據(jù)
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
JHDownloadInfo *info = [self downloadInfoForURL:dataTask.taskDescription];
[info didReceiveData:data];
// 回調(diào)更新UI
if([self.downloadDelegate respondsToSelector:@selector(updateCellProgress:)]) {
[self.downloadDelegate updateCellProgress:info];
}
}
/**
* 服務(wù)器結(jié)束響應(yīng)
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
JHDownloadInfo *info = [self downloadInfoForURL:task.taskDescription];
[info didCompleteWithError:error];
[self resumeFirstWillResume];
// 更新本地Plist表
[self addToLocalPlist:info];
// 回調(diào)下載完成
if([self.downloadDelegate respondsToSelector:@selector(finishedDownload:)]) {
[self.downloadDelegate finishedDownload:info];
}
}
下載數(shù)據(jù)本地化
/**
* 獲取已下載文件
*/
-(NSArray*)getDownloadedFile
{
NSString *downloadedPlistPath = [[NSString stringWithFormat:@"%@/%@", JHDownloadRootDir, @"DownloadedInfo.plist"] prependCaches];
NSArray *downloadedDictArray = [NSArray arrayWithContentsOfFile:downloadedPlistPath];
NSArray *downloadedModelArray = [JHDownloadInfo mj_objectArrayWithKeyValuesArray:downloadedDictArray];
return downloadedModelArray;
}
/**
* 獲取正下載文件
*/
-(NSArray*)getDownloadingFile
{
NSString *downloadingPlistPath = [[NSString stringWithFormat:@"%@/%@", JHDownloadRootDir, @"DownloadingInfo.plist"] prependCaches];
NSArray *downloadingDictArray = [NSArray arrayWithContentsOfFile:downloadingPlistPath];
NSArray *downloadingModelArray = [JHDownloadInfo mj_objectArrayWithKeyValuesArray:downloadingDictArray];
return downloadingModelArray;
}
/**
* 刪除某一個文件
*/
-(void)delete:(JHDownloadInfo*)info{
// 修改Plist
[self deleteLocalPlist:info];
// 刪除文件
if ([[NSFileManager defaultManager] fileExistsAtPath:info.file]) {
[[NSFileManager defaultManager] removeItemAtPath:info.file error:nil];
}
}
/**
* 修改本地Plist
*/
- (void)deleteLocalPlist:(JHDownloadInfo*)fileinfo{
NSString *plistPath = [[NSString stringWithFormat:@"%@/%@", JHDownloadRootDir, @"DownloadingInfo.plist"] prependCaches];
if (fileinfo.state == JHDownloadStateCompleted){
plistPath = [[NSString stringWithFormat:@"%@/%@", JHDownloadRootDir, @"DownloadedInfo.plist"] prependCaches];
}
NSMutableArray *downloadingArray = [[NSMutableArray alloc] initWithContentsOfFile:plistPath];
[downloadingArray enumerateObjectsUsingBlock:^(NSDictionary *dict, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *url = [dict objectForKey:@"url"];
if ([url isEqualToString:fileinfo.url]) [downloadingArray removeObject:dict];
}];
[downloadingArray writeToFile:plistPath atomically:YES];
}
/**
* 添加本地Plist
*/
- (void)addToLocalPlist:(JHDownloadInfo*)fileinfo
{
NSDictionary *fileDic = [fileinfo mj_keyValuesWithKeys:@[@"state",@"bytesWritten",@"totalBytesWritten",@"totalBytesExpectedToWrite",@"filename",@"file",@"url"]];
NSString *plistPath = [[NSString stringWithFormat:@"%@/%@", JHDownloadRootDir, @"DownloadingInfo.plist"] prependCaches];
if (fileinfo.state == JHDownloadStateCompleted){
// 移除正下載
NSMutableArray *downloadingArray = [[NSMutableArray alloc] initWithContentsOfFile:plistPath];
[downloadingArray enumerateObjectsUsingBlock:^(NSDictionary *dict, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *url = [dict objectForKey:@"url"];
if ([url isEqualToString:fileinfo.url]) [downloadingArray removeObject:dict];
}];
[downloadingArray writeToFile:plistPath atomically:YES];
// 添加新路徑
plistPath = [[NSString stringWithFormat:@"%@/%@", JHDownloadRootDir, @"DownloadedInfo.plist"] prependCaches];
}
if([[NSFileManager defaultManager] fileExistsAtPath:plistPath]){
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:plistPath];
[array addObject:fileDic];
BOOL success = [array writeToFile:plistPath atomically:YES];
NSLog(@"%@",success?@"寫入成功":@"寫入失敗");
}else{
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:fileDic];
BOOL success = [array writeToFile:plistPath atomically:YES];
NSLog(@"%@",success?@"寫入成功":@"寫入失敗");
}
}
創(chuàng)建任務(wù)
-
NSURLSession:NSURLSessionConfiguration毁枯、NSOperationQueue
- (NSURLSession *)session
{
if (!_session) {
// 配置
NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration defaultSessionConfiguration];
// session
self.session = [NSURLSession sessionWithConfiguration:cfg delegate:self delegateQueue:self.queue];
}
return _session;
}
- (NSOperationQueue *)queue
{
if (!_queue) {
self.queue = [[NSOperationQueue alloc] init];
self.queue.maxConcurrentOperationCount = 1;
}
return _queue;
}
-
NSURLSessionDataDelegate
1、開始響應(yīng)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
// 獲得下載信息
DownloadInfo *info = [self downloadInfoForURL:dataTask.taskDescription];
// 處理響應(yīng)
[info didReceiveResponse:response];
// 繼續(xù)
completionHandler(NSURLSessionResponseAllow);
}
2叮称、正在響應(yīng)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
// 獲得下載信息
DownloadInfo *info = [self downloadInfoForURL:dataTask.taskDescription];
// 處理數(shù)據(jù)
[info didReceiveData:data];
}
3种玛、結(jié)束響應(yīng)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
// 獲得下載信息
DownloadInfo *info = [self downloadInfoForURL:task.taskDescription];
// 處理結(jié)束
[info didCompleteWithError:error];
// 恢復(fù)等待下載的
[self resumeFirstWillResume];
}
開始任務(wù)
-
獲取下載模型
DownloadInfo *info = [self downloadInfoForURL:url];
#pragma mark - 獲得下載信息
- (DownloadInfo *)downloadInfoForURL:(NSString *)url
{
if (url == nil) return nil;
DownloadInfo *info = [self.downloadInfoArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"url==%@", url]].firstObject;
if (info == nil) {
info = [[DownloadInfo alloc] init];
info.url = url; // 設(shè)置url
[self.downloadInfoArray addObject:info];
}
return info;
}
-
最大并發(fā)數(shù)Vs當(dāng)前正下載
NSArray *downloadingDownloadInfoArray = [self.downloadInfoArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"state==%d", MJDownloadStateResumed]];
if (self.maxDownloadingCount && downloadingDownloadInfoArray.count == self.maxDownloadingCount) {
// 等待下載
[info willResume];
} else {
// 開始下載
[info resume];
}
-
等待下載
/** 任務(wù) */
@property (strong, nonatomic) NSURLSessionDataTask *task;
-
開始下載
/** 任務(wù) */
@property (strong, nonatomic) NSURLSessionDataTask *task;
[self.task resume];
初始化下載管理器
-
下載完成
/**
* 服務(wù)器結(jié)束響應(yīng)
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
JHDownloadInfo *info = [self downloadInfoForURL:task.taskDescription];
[info didCompleteWithError:error];
[self resumeFirstWillResume];
if (!error) [self saveDownloadFile:info];
}
/**
* 存儲已下載文件
*/
- (void)saveDownloadFile:(JHDownloadInfo*)fileinfo
{
NSString *downloadedPlistPath = [[NSString stringWithFormat:@"%@/%@", JHDownloadRootDir, @"DownloadedInfo.plist"] prependCaches];
NSDictionary *fileDic = [fileinfo mj_keyValues];
if([[NSFileManager defaultManager] fileExistsAtPath:downloadedPlistPath]){
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:downloadedPlistPath];
[array addObject:fileDic];
BOOL success = [array writeToFile:downloadedPlistPath atomically:YES];
NSLog(@"%@",success?@"寫入成功":@"寫入失敗");
}else{
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:fileDic];
BOOL success = [array writeToFile:downloadedPlistPath atomically:YES];
NSLog(@"%@",success?@"寫入成功":@"寫入失敗");
}
}
/**
* 刪除已下載的文件
*/
- (void)deleteFinishFile:(ZFFileModel *)selectFile
{
[_finishedlist removeObject:selectFile];
NSFileManager *fm = [NSFileManager defaultManager];
NSString *path = FILE_PATH(selectFile.fileName);
if ([fm fileExistsAtPath:path]) {
[fm removeItemAtPath:path error:nil];
}
[self saveFinishedFile];
}
-
下載中
/**
* 下載文件所有信息存儲為plist
*/
- (void)saveDownloadFile:(ZFFileModel*)fileinfo
{
NSData *imagedata = UIImagePNGRepresentation(fileinfo.fileimage);
NSDictionary *filedic = [NSDictionary dictionaryWithObjectsAndKeys:fileinfo.fileName,@"filename",
fileinfo.fileURL,@"fileurl",
fileinfo.time,@"time",
fileinfo.fileSize,@"filesize",
fileinfo.fileReceivedSize,@"filerecievesize",
imagedata,@"fileimage",nil];
NSString *plistPath = [fileinfo.tempPath stringByAppendingPathExtension:@"plist"];
if (![filedic writeToFile:plistPath atomically:YES]) {
NSLog(@"write plist fail");
}
}
/*
* 將本地的未下載完成的臨時文件加載到正在下載列表里,但是不接著開始下載
*/
- (void)loadTempfiles
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *filelist = [fileManager contentsOfDirectoryAtPath:TEMP_FOLDER error:&error];
if(!error)
{
NSLog(@"%@",[error description]);
}
NSMutableArray *filearr = [[NSMutableArray alloc]init];
for(NSString *file in filelist) {
NSString *filetype = [file pathExtension];
if([filetype isEqualToString:@"plist"])
[filearr addObject:[self getTempfile:TEMP_PATH(file)]];
}
NSArray* arr = [self sortbyTime:(NSArray *)filearr];
[_filelist addObjectsFromArray:arr];
[self startLoad];
}