标签:
//
// Download.m
// LessonDownLoad
//
// Created by zhangxu on 15/11/11.
// Copyright © 2015年 zhangxu. All rights reserved.
//
#import "Download.h"
@interface Download ()
@property (nonatomic,strong) NSURLSessionDownloadTask *task;
@property (nonatomic,strong) NSURLSession *session;
@end
@implementation Download{
BOOL _isFirst;// 第一次走下载进度的时候,进行暂停保存数据
}
- (void)dealloc
{
NSLog(@"对象被销毁");
}
// 根据URL创建一个下载类
- (instancetype)initWithURL:(NSString *)urlString{
if (self = [super init]) {
_url = urlString;// 给我门的属性赋值
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
self.session = session;
// 先去数据库中查找是否已经下载了 如果已经下载了 我门就把_isFist 赋值为YES 防止我门重复添加数据
_isFirst = [DB findDownloadingWithURL:urlString];
self.task = [session downloadTaskWithURL:[NSURL URLWithString:urlString]];
// 如果已经下载了 我门更换我门的task
if (_isFirst) {
self.task = [self.session downloadTaskWithResumeData:[self resumeDataWithURL:urlString]];
}
}
return self;
}
- (NSData *)resumeDataWithURL:(NSString *)url{
// 1、找到下载中的model
DownloadingManagment *downloading = [DB findDownloadingWithURL:url];
// 2、获取当前下载文件的大小
NSFileManager *fm = [NSFileManager defaultManager];
NSString *nowFileSize = [NSString stringWithFormat:@"%llu",[fm attributesOfItemAtPath:downloading.filePath error:nil].fileSize];
// 3、对resumeData 进行更替
downloading.resumeDataStr = [downloading.resumeDataStr stringByReplacingOccurrencesOfString:downloading.fileSize withString:nowFileSize];
// 4、生成 NSData 进行返回
return [downloading.resumeDataStr dataUsingEncoding:NSUTF8StringEncoding];
}
- (void)downloadComplted:(DownloadComlted)downloadConplted{
self.complted = downloadConplted;
}
- (void)downloadFinish:(DownloadFinish)downloadFinish Downloading:(Downloading)downloading{
self.downloadFinish = downloadFinish;
self.downloading = downloading;
}
// 开始继续
- (void)resume{
[self.task resume];
}
// 暂停
- (void)suspend{
[self.task suspend];
// [self.task cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
//
//
// NSString *resumeDataStr = [[NSString alloc] initWithData:resumeData encoding:NSUTF8StringEncoding];
//// NSLog(@"%@",resumeDataStr);
// }];
}
#pragma mark - 下载完成调用delegate 方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
NSString *cache = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, nil)[0];
NSString *savePath = [cache stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
NSFileManager *manager = [NSFileManager defaultManager];
[manager moveItemAtPath:location.path toPath:savePath error:nil];
// 保存数据库
DownloadManagmentFinish *finish = [[DownloadManagmentFinish alloc] init];
finish.url = self.url;
finish.savePath = savePath;
[DB addDownloadFinishWithFinish:finish];
if (self.downloadFinish) {
self.downloadFinish(savePath);
}
// 下载完成以后 回调 目的是让
if (self.complted) {
self.complted(_url);
}
}
#pragma mark - 下载中的代理方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
// 定义一个bool 值NO 的时候 进行暂停 暂停的时候 把resumeData 解析保存 然后把值设置为YES 让它继续下载 就不会再走这个暂停方法了
if (_isFirst == NO) {
// 执行暂停方法
[self cancleDownloadTask];
_isFirst = YES;
}
float progress = (float)totalBytesWritten/totalBytesExpectedToWrite;
// 对数据库中的下载的进度做一个更新
[DB updateDownloadProgress:(int)(progress*100) WithURL:self.url];
// [self.delegate changeProgress:progress];
// NSLog(@"%f",progress);
if (self.downloading) {
self.downloading(progress*100,bytesWritten);
}
}
// 暂停task方法
- (void)cancleDownloadTask{
__weak typeof(self) vc = self;
[self.task cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
// 解析保存 resumeData
[self parsingResumeData:resumeData];
// 继续开始下载
vc.task = [self.session downloadTaskWithResumeData:resumeData];
[vc.task resume];
}];
}
// 解析保存 resumeData
- (void)parsingResumeData:(NSData *)resumeData{
NSString *resumeDataStr = [[NSString alloc] initWithData:resumeData encoding:NSUTF8StringEncoding];
NSLog(@"%@",resumeDataStr);
// 获取fileSize 字节
NSString *fileSize = [resumeDataStr componentsSeparatedByString:@"<key>NSURLSessionResumeBytesReceived</key>\n\t<integer>"].lastObject;
// fileSize = [fileSize componentsSeparatedByString:@"</integer>"].firstObject;
// NSString *fileSize = [resumeDataStr componentsSeparatedByString:@"<key>NSURLSessionResumeBytesReceived</key>\n\t<integer>"].lastObject;
fileSize = [fileSize componentsSeparatedByString:@"</integer>"].firstObject;
NSLog(@"==============%@",fileSize);
// 截取filePath
// Xcode7 文件的截取
NSString *filePath = [filePath componentsSeparatedByString:@"<key>NSURLSessionResumeInfoTempFileName</key>\n\t<string>"].lastObject;
filePath = [filePath componentsSeparatedByString:@"</string>"].firstObject;
// xcode 截取的 需要做一个拼接 怎么获取到tmp 的文件路径
NSString *tmp = NSTemporaryDirectory();
filePath = [tmp stringByAppendingPathComponent:filePath];
NSLog(@"%@",filePath);
// 还要解析Xcode6下的文件
NSFileManager *fm = [NSFileManager defaultManager];
if ([fm fileExistsAtPath:filePath] == NO) {
// 如果我门获取到的路径打不开 就换种解析方法
filePath = [resumeDataStr componentsSeparatedByString:@"<key>NSURLSessionResumeInfoLocalPath</key>\n\t<string>"].lastObject;
}
//
// 进行保存数据到数据库
DownloadingManagment *downloading = [[DownloadingManagment alloc] init];
downloading.resumeDataStr = resumeDataStr;
downloading.filePath = filePath;
downloading.fileSize = fileSize;
downloading.url = self.url;
// 保存数据库
[DB addDownloadingWithDownloading:downloading];
// 我门需要把数据库保存当前的信息
/*
1、resumeDataStr (NSString) 保存我门resumeData的数据 取出的时候做一个转码
2、filePath (NSString) 我门要找到文件的路径 并且求出大小 做替换
3、fileSize (int) 保存暂停resumeData 的中保存的文件大小要知道和谁做替换
4、progress (float) 下载的进度是多少
5、URL (NSString) 唯一表示 让我门知道再那里能找到这条数据
6、time (double) 添加下载的时间戳 (创建数据库的时候 都带上这个属性,一定会用到,比如我门要做一个排序)
*/
// 下载完成需要的属性
/*
1.url (NSString)唯一标识 让我门知道再那里能找到这条数据
2.savePath (NSString) 保存的路径
3.time (double) 时间
*/
}
@end
标签:
原文地址:http://www.cnblogs.com/kzw6412/p/5102154.html