断点下载

演示效果如下:

利用NSURLSession实现断点下载

1.属性

@interface ViewController ()<NSURLSessionDownloadDelegate>
/** 下载任务 */
@property (nonatomic,strong) NSURLSessionDownloadTask *task;

/** 上次的下载信息 */
@property (nonatomic,strong) NSData *resumeData;


/** session */
@property (nonatomic,strong) NSURLSession *session;
@end

2.初始化属性

- (NSURLSession *)session {
    if (!_session) {
        _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
    }
    return _session;
}

- (NSData *)resumeData {
    //第一次访问resumeData加载沙盒中的resumeData
    if (!_resumeData) {
        NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
        
        NSString *file = [caches stringByAppendingPathComponent:@"data"];
        _resumeData = [NSData dataWithContentsOfFile:file];
    }
    return _resumeData;
}

3.实现点击事件

/**
 * 开始下载
 */
- (IBAction)start:(id)sender {
    
    //获得下载任务
    self.task = [self.session downloadTaskWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4"]];
    
    //启动任务
    [self.task resume];
}
/**
 * 暂停下载
 */
- (IBAction)pause:(id)sender {
    //一旦这个task被取消了,就无法再恢复
    //data里面存储着上次的下载信息
    [self.task cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
        self.resumeData = resumeData;
        
        //可以将resumeData放到沙盒中
        NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
        
        NSString *file = [caches stringByAppendingPathComponent:@"data"];
        [resumeData writeToFile:file atomically:YES];
    }];
}
/**
 * 继续下载
 */
- (IBAction)goOn:(id)sender {
    self.task = [self.session downloadTaskWithResumeData:self.resumeData];
    [self.task resume];
}

4.实现代理方法

#pragma mark -<NSURLSessionDownloadDelegate>

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes {
     NSLog(@"%s",__func__);
}


/**
 * 每当写入数据到临时文件中时,就会调用一次
 * totalBytesExpectedToWrite:总大小
 * totalBytesWritten:已经写入的大小
 * bytesWritten 这次写入大小
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
    NSLog(@"%s",__func__);
    
    NSLog(@"------%f",1.0*totalBytesWritten/totalBytesExpectedToWrite);
}

/**
 * 下载完毕就会调用一次这个方法
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
     NSLog(@"%s",__func__);
    //文件将来存放的真实路径
    NSString *file = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
    
    
    //剪切location的临时文件到真实路径
    NSFileManager *manager = [NSFileManager defaultManager];
    [manager moveItemAtURL:location toURL:[NSURL fileURLWithPath:file] error:nil];
}


- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    NSLog(@"%s",__func__);

    //保存恢复数据

    self.resumeData = error.userInfo[NSURLSessionDownloadTaskResumeData];


}

怎么实现的断点下载?

resumeData里面保存了上次下载的信息

/**

 * 请求这个http://120.25.226.186:32812/resources/videos/minion_02.mp4路径

 * 设置请求头 

 * Range: 0-100

 * [[NSMutableURLRequest requestWithURL:nil] setValue:@"0-1024" forHTTPHeaderField:@"Range"];

 * 通过设置Range这个请求头可以控制下载哪一部分的信息

 */

这些在resumeData都帮你做好了
原文地址:https://www.cnblogs.com/langji/p/5373615.html