断点续传

暂停继续

  • 定义属性
///  下载任务
@property (nonatomic, strong) NSURLSessionDownloadTask *task;
///  续传数据
@property (nonatomic, strong) NSData *resumeData;
  • 代码实现
- (IBAction)start {
    if (self.task != nil) {
        NSLog(@"已经存在下载任务 %@", self.task);

        if (self.task.state == NSURLSessionTaskStateSuspended) {
            [self.task resume];
        } else {
            [self.task suspend];
        }

        return;
    }

    NSURL *url = [NSURL URLWithString:@"http://dldir1.qq.com/qqfile/QQforMac/QQ_V4.0.2.dmg"];

    NSLog(@"start");
    // 直接建立下载任务并且启动,后续的进度监听又代理负责
    self.task = [self.session downloadTaskWithURL:url];
    [self.task resume];
}

下载结束处理

按照 suggestedFilename 保存文件

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
    NSLog(@"%@", location);
    NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
    [[NSFileManager defaultManager] copyItemAtPath:location.path toPath:filePath error:NULL];
}

使用 MD5 URL 保存文件

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
    NSLog(@"%@", location);
    NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:downloadTask.response.URL.absoluteString.md5String];
    NSLog(@"%@", filePath.fileMD5Hash);
    [[NSFileManager defaultManager] copyItemAtPath:location.path toPath:filePath error:NULL];
}

基本功能实现

  • 定义属性
///  下载任务
@property (nonatomic, strong) NSURLSessionDownloadTask *downloadTask;
///  续传数据
@property (nonatomic, strong) NSData *resumeData;
  • 开始下载
- (IBAction)start {

    if (self.downloadTask != nil) {
        NSLog(@"正在玩命下载中...");
        return;
    }

    NSURL *url = [NSURL URLWithString:@"http://dldir1.qq.com/qqfile/QQforMac/QQ_V4.0.2.dmg"];

    self.downloadTask = [self.session downloadTaskWithURL:url];
    [self.downloadTask resume];
}
  • 暂停
- (IBAction)pause {
    NSLog(@"暂停");
    [self.downloadTask cancelByProducingResumeData:^(NSData *resumeData) {
        NSLog(@"pause %tu", resumeData.length);
        self.resumeData = resumeData;
        self.downloadTask = nil;
    }];
}
  • 继续
- (IBAction)resume {

    if (self.resumeData == nil) {
        NSLog(@"没有续传数据");
        return;
    }

    self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];

    self.resumeData = nil;

    [self.downloadTask resume];
}

方法整合

- (IBAction)start {
    if (self.task != nil || self.resumeData != nil) {
        NSLog(@"已经存在下载任务 %@", self.task);

        if (self.resumeData != nil) {
            self.task = [self.session downloadTaskWithResumeData:self.resumeData];
            [self.task resume];

            self.resumeData = nil;
        } else {
            NSLog(@"取消");

            [self.task cancelByProducingResumeData:^(NSData *resumeData) {
                NSLog(@"%tu", resumeData.length);
                self.resumeData = resumeData;
                self.task = nil;
            }];
        }

        return;
    }

    NSURL *url = [NSURL URLWithString:@"http://dldir1.qq.com/qqfile/QQforMac/QQ_V4.0.2.dmg"];

    NSLog(@"start");
    // 直接建立下载任务并且启动,后续的进度监听又代理负责
    self.task = [self.session downloadTaskWithURL:url];
    [self.task resume];
}

续传数据

  • 将续传数据写入磁盘,会发现是一个 plist
  • 优化续传代码
///  返回下载文件 URL 的续传数据路径
///
///  @param url 下载文件的 URL
///
///  @return 续传数据路径
- (NSString *)resumePath:(NSURL *)url {
    NSString *resumePath = [NSTemporaryDirectory() stringByAppendingPathComponent:url.absoluteString.md5String];
    return [resumePath stringByAppendingPathExtension:@"~resume"];
}

///  加载 URL 对应的续传数据
///
///  @param url 下载文件的 url
///
///  @return 如果存在返回上次续传数据
- (NSData *)loadResumeData:(NSURL *)url {

    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:[self resumePath:url]];
    // 提取缓存路径名
    NSString *tmpFileName = dict[@"NSURLSessionResumeInfoLocalPath"];
    // 重新生成缓存路径名
    NSString *fileName = [NSTemporaryDirectory() stringByAppendingPathComponent:[tmpFileName lastPathComponent]];
    dict[@"NSURLSessionResumeInfoLocalPath"] = fileName;

    // 删除续传文件
    [[NSFileManager defaultManager] removeItemAtPath:[self resumePath:url] error:NULL];

    // PList 序列化
    return [NSPropertyListSerialization dataWithPropertyList:dict format:NSPropertyListXMLFormat_v1_0 options:0 error:NULL];
}

results matching ""

    No results matching ""