码迷,mamicode.com
首页 > 其他好文 > 详细

断点下载

时间:2016-01-05 15:21:44      阅读:411      评论:0      收藏:0      [点我收藏+]

标签:

//

//  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];

    

    

    // 我门需要把数据库保存当前的信息

    /*

     1resumeDataStr (NSString)  保存我门resumeData的数据 取出的时候做一个转码

     2filePath (NSString)  我门要找到文件的路径 并且求出大小 做替换

     3fileSize (int) 保存暂停resumeData 的中保存的文件大小要知道和谁做替换

     4progress (float) 下载的进度是多少

     5URL (NSString)  唯一表示 让我门知道再那里能找到这条数据

     6time (double)  添加下载的时间戳  (创建数据库的时候 都带上这个属性,一定会用到,比如我门要做一个排序)

     

     

     */

    

    

    // 下载完成需要的属性

    /*

     1.url (NSString)唯一标识 让我门知道再那里能找到这条数据

     2.savePath (NSString) 保存的路径

     3.time (double) 时间

     

     */

 

}

 

@end

断点下载

标签:

原文地址:http://www.cnblogs.com/kzw6412/p/5102154.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!