初始化下载管理器
1、遍历正下载Plist的所有字典成模型数组
2、给所有下载模型赋值Task
3、计算所有模型的已下载大小
4、将模型数组赋值给下载管理器的临时数组
添加下载
1、判断当前url文件的下载状态(已下载、正下载、未下载)
2、
下载数据管理
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、计算已下载文件的大小,方便继续断点下载
创建请求
-
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 ---------------------------------------
/**
* 服务器开始响应
*/
- (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];
// 回调开始下载
if([self.downloadDelegate respondsToSelector:@selector(startDownload:)]) {
[self.downloadDelegate startDownload:info];
}
// 继续
completionHandler(NSURLSessionResponseAllow);
}
/**
* 服务器发送数据
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
JHDownloadInfo *info = [self downloadInfoForURL:dataTask.taskDescription];
[info didReceiveData:data];
// 回调更新UI
if([self.downloadDelegate respondsToSelector:@selector(updateCellProgress:)]) {
[self.downloadDelegate updateCellProgress:info];
}
}
/**
* 服务器结束响应
*/
- (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];
// 回调下载完成
if([self.downloadDelegate respondsToSelector:@selector(finishedDownload:)]) {
[self.downloadDelegate finishedDownload:info];
}
}
下载数据本地化
/**
* 获取已下载文件
*/
-(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?@"写入成功":@"写入失败");
}
}
创建任务
-
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、开始响应
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
// 获得下载信息
DownloadInfo *info = [self downloadInfoForURL:dataTask.taskDescription];
// 处理响应
[info didReceiveResponse:response];
// 继续
completionHandler(NSURLSessionResponseAllow);
}
2、正在响应
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
// 获得下载信息
DownloadInfo *info = [self downloadInfoForURL:dataTask.taskDescription];
// 处理数据
[info didReceiveData:data];
}
3、结束响应
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
// 获得下载信息
DownloadInfo *info = [self downloadInfoForURL:task.taskDescription];
// 处理结束
[info didCompleteWithError:error];
// 恢复等待下载的
[self resumeFirstWillResume];
}
开始任务
-
获取下载模型
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; // 设置url
[self.downloadInfoArray addObject:info];
}
return info;
}
-
最大并发数Vs当前正下载
NSArray *downloadingDownloadInfoArray = [self.downloadInfoArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"state==%d", MJDownloadStateResumed]];
if (self.maxDownloadingCount && downloadingDownloadInfoArray.count == self.maxDownloadingCount) {
// 等待下载
[info willResume];
} else {
// 开始下载
[info resume];
}
-
等待下载
/** 任务 */
@property (strong, nonatomic) NSURLSessionDataTask *task;
-
开始下载
/** 任务 */
@property (strong, nonatomic) NSURLSessionDataTask *task;
[self.task resume];
初始化下载管理器
-
下载完成
/**
* 服务器结束响应
*/
- (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];
}