iOS干货开发你可不能输!iOS 开发

iOS原生文件的下载

2015-10-02  本文已影响4027人  Little_Dragon

小文件的下载

NSData直接从URL中加载数据

系统提供了方法, 让很多东西都可以直接转换成二进制数据的类型(可以从URL加载,file加载等等,单一数据,直接写入)

// 从提供URL中下载数据
 NSData *data = [NSData dataWithContentsOfURL:
                    [NSURL URLWithString: @"http://b.hiphotos.baidu.com/zhidao/pic/item/728da9773912b31b31187e8c8418367adab4e11b.jpg"]];
// 数据转换成图片
    UIImage *image = [UIImage imageWithData:data    ];
    self.imageView.image = image; 
    // 将图片数据,转换成data数据
    NSData *data1 = UIImageJPEGRepresentation(image, 0);
    // 将data数据,进行保存
    [data1 writeToFile:@"/Users/liujiaxin/Desktop/image.jpeg" atomically:YES];
NSURLConnection如果是小文件的话,直接异步请求便能得到相应的数据.

    NSURL *url = [NSURL URLWithString:@"http://www.people.com.cn/mediafile/pic/20150811/19/7260132349722664171.jpg"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
  // 发送请求
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        // 主队列回调 赋值UI
        self.imageView.image = [UIImage imageWithData:data];
    }];
NSURLSession

IOS7以后不建议使用NSURLConnection进行网络数据处理. [session更加灵活,将操作封装到任务中,通过对任务的操作能够精确的控制操作]NSURLSession, 相当于处理放在会话层执行 (有点大一统的想法, 因为二维码相关的也需要会话)
NSURLSessionTask


    /**
     *  步骤
     *  1、创建task(任务)【任务分为:downloadTask, dataTask(uploadTask)】
     *  2、利用 session 创建 task
     *  3、创建 session
     *  4、执行task   - resume 重新执行
     */
    
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST";
    request.HTTPBody = [@"username=520it&pwd=520it" dataUsingEncoding:NSUTF8StringEncoding];
    
    NSURLSession *session = [NSURLSession sharedSession];

    // 可以不必创建请求直接用url进行获取,但是只能应用于get请求
    
    NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
    }];  
    [task resume];
NSURLSessionDownloadTask
NSURLSession *session = [NSURLSession sharedSession];
    
    /**
     *  创建下载任务 (该任务启动后便会自己进行下载,并存储的)
     *
     *  @param NSURL 下载那个url 的任务
     *
     *  @block 中的数据 location下载好的文件放在磁盘的位置(会自己创建一个临时文件夹的临时目录)
     *           临时目录存放文件,会不定时的删除, 所以最后将文件转移到Cache中
     *    响应头
     */
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_02.png"];
    NSURLSessionDownloadTask *task = [session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
        NSFileManager *mgr = [NSFileManager defaultManager];
//        [mgr createFileAtPath:[response.suggestedFilename cacheDir] contents:nil attributes:nil];
        // 将文件原存储的的地址 ,转换成新的存储地址, (将沙盒cache地址 用url 进行转换)。
        [mgr moveItemAtURL:location toURL:[NSURL fileURLWithPath:[response.suggestedFilename cacheDir]] error:nil];
        NSLog(@"%@",[response.suggestedFilename cacheDir]); 
    }];
    [task resume];

大文件下载

NSURLConnection,在网络一章中已经说明,对于文件的下载上传管理都是交由代理来完成的.
NSURLConnection的代理方法有:NSURLConnectionDataDelegate
1.接收到响应式调用
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response
2.接收到数据时调用
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data[会调用多次, 每次接受文件是由限制的. 所以会进行多次调用,我们需要将每次接受到的数据进行拼接]
3.连接失败时调用
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
4.接收数据完成时调用
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
在大文件下载之前,我们还需要考虑的是,
1>数据放在应用中,建立一个容器专门存放数据,这样调用虽然方便,但是数据存放在应用中,必定会消耗一定的内存,而且会消耗一定得性能.将读取到的数据,存放在沙盒文件中
2>在沙盒中建立文件,存放数据.(一边下载,一边存放)然后将已经保存的数据进行读取就可以了
第一种方案:

// 建立一个容器数据,用来保存下载后的数据(但由于,数据一致存在于内存,所以非常耗性能)
@property(strong,nonatomic) NSMutableData *data;
- (NSMutableData *)data
{
    if (!_data) {
        _data = [NSMutableData data];
    }
    return _data;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    NSString *urlStr = [ @"http://120.25.226.186:32812" stringByAppendingPathComponent: @"resources/videos/minion_01.mp4"];
    NSURL *url =  [NSURL URLWithString:urlStr];
 // 设置请求   
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 设置URLConnection,并且设置代理   
 NSURLConnection *urlCon = [NSURLConnection connectionWithRequest:request delegate:self];   
}

// 代理方法。开始接受相应的时候调用
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response
{
    // 由协议头 取出 接收数据的总长度
    self.AllLength = response.expectedContentLength;
}

// 开始接收到数据的时候调用
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{

    // 拼接数据
    [self.data appendData:data];   
  // 取出当前文件下载长度
    self.currentLength += data.length; 
    // 得到控件sliderView的值
    self.slideView.value = 1.0 * self.currentLength / self.AllLength; 
}
// 失败时调用
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
 NSLog(@"%s",__func__);
    
}

// 完成时调用
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// 完成时 将拼接数据保存
    [self.data writeToFile:[@"minion_01.mp4" cacheDir] atomically:YES];
}

第二种方案:
沙盒建立文件,存放下载数据

- (void)viewDidLoad {
    [super viewDidLoad];
   
    NSString *urlStr = [ @"http://120.25.226.186:32812" stringByAppendingPathComponent: @"resources/videos/minion_01.mp4"];
    NSURL *url =  [NSURL URLWithString:urlStr];
    
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLConnection *urlCon = [NSURLConnection connectionWithRequest:request delegate:self];
    
}
// 代理方法。开始接受相应的时候调用
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response
{
    
    // 由协议头 取出 接收数据的总长度
    self.AllLength = response.expectedContentLength;
// 只有利用manager 才能建立文件       
 NSFileManager *mgr = [NSFileManager defaultManager];
    // 有协议头 得到,接收到文件的名称
         NSString *filePath = [response.suggestedFilename cacheDir];
        NSLog(@"%@",filePath);
        self.filePath = filePath;
        [mgr createFileAtPath:filePath contents:NULL attributes:NULL];   
}
// 开始接收到数据的时候调用
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{

    // 拼接数据
//    [self.data appendData:data];
// 建立文件句柄 --- 主要用于文件数据处理   
 NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:self.filePath];
    // 将后一个数据写在前一个数据的后面
    [handle seekToEndOfFile];
    // 写数据
    [handle writeData:data];
    // 取出当前文件下载长度
    self.currentLength += data.length;
    // 得到控件sliderView的值
    self.slideView.value = 1.0 * self.currentLength / self.AllLength;    
}
// 失败时调用
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
 NSLog(@"%s",__func__);   
}
// 完成时调用
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// 完成时 将拼接数据保存
//    [self.data writeToFile:[@"minion_01.mp4" cacheDir] atomically:YES];
}

第三种情况:当出现网络情况很差,或者出现断网的情况,这样的话,如果下载到99.9%,然后断网,在进行下载的话,是不是很坑呢.....
所以应该我们需要进行断点续传
断点续传的实现.
协议头,我们需要传入这么一个参数Range: 将这么一个参数设置的话, 就想到与告诉服务请,请求的数据的范围从什么地方开始,所以我们如果告诉服务器范围(文件已经下载的大小),就可以了

- (IBAction)btnClick:(UIButton *)sender {
    // 1.切换按钮图片
    sender.selected = !sender.selected;
    // 2.判断是否是继续下载
    if (sender.selected) {
        // 继续下载
        NSLog(@"继续下载");
        NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4"];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        // 只要设置HTTP请求头的Range属性, 就可以实现从指定位置开始下载
        /*
         表示头500个字节:Range: bytes=0-499
         表示第二个500字节:Range: bytes=500-999
         表示最后500个字节:Range: bytes=-500
         表示500字节以后的范围:Range: bytes=500-
         */
        NSString *range = [NSString stringWithFormat:@"bytes %zd-", self.currentLength]; 
        [request setValue:range forHTTPHeaderField:@"Range"];
        
        self.con = [NSURLConnection connectionWithRequest:request delegate:self];
    }else
    {
        // 暂停
        NSLog(@"暂停");
        [self.con cancel];
    }
}

// 接收到服务器的响应
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response
{
    self.totalLength = response.expectedContentLength;
    // 先去文件中获取下载进度
    
    // 并不是每次都需要创建文件
    // 如果已经下载了一部分, 就继续在上一个文件的后面添加
    if (self.currentLength > 0) {
        return;
    }
    
    
    // 创建容器
    // 创建一个空的文件, 用于保存下载的数据
    NSFileManager *manager = [NSFileManager defaultManager];
    NSString *path = [response.suggestedFilename cacheDir];
    NSLog(@"path = %@", path);
    [manager createFileAtPath:path contents:nil attributes:nil];
    self.path = path;
}

// 接收到服务器返回的数据
// 会调用一次或多次
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{

    // 1.创建一个操作文件的句柄
//    NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:self.path];
    
    // 设置数据写入的位置
    // 只要调用这个方法, 每次写入数据都会写入到上一次的后面
    [self.handle seekToEndOfFile];
    
    // 2.利用句柄往文件中写入数据
    [self.handle writeData:data];
    
    // 3.计算当前接收到得数据的总数
    self.currentLength += data.length;
    
    // 计算下载比例
    self.progressView.progress = 1.0 * self.currentLength/self.totalLength;
}

// 接收完毕
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [self.handle closeFile];
    self.handle = nil;
    
    NSLog(@"下载完毕");
}
#pragma mark - lazy 
- (NSFileHandle *)handle
{
    if (!_handle) {
        // 1.创建一个操作文件的句柄
        _handle = [NSFileHandle fileHandleForWritingAtPath:self.path];
    }
    return _handle;
}

第四种方式 : 句柄 (太陌生), 输出数据流进行数据的存储(根据文件创建数据输出流, 数据流,只接受byte数据 )


// 设置按钮的监听
- (IBAction)clickBtn:(UIButton *)sender;
// 创建网络请求连接
@property (strong, nonatomic) NSURLConnection *con;
// 记录接收文件的总大小
@property (assign, nonatomic) NSInteger totalLength;
// 记录接收到的当前文件的大小
@property (assign, nonatomic) NSInteger currentLength;
// 记录文件存储路径
@property (copy, nonatomic) NSString *toPath;
// 设置输出流,用于接收数据
@property (strong, nonatomic)  NSOutputStream *stream;
@end

@implementation ViewController

- (IBAction)clickBtn:(UIButton *)sender {
    
    sender.selected = !sender.selected;

    if (sender.selected) {
        
        NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4"];
        
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        // 拼接请求头
        NSString *range = [NSString stringWithFormat:@"bytes %zd-", self.currentLength];
        [request setValue:range forHTTPHeaderField:@"Range"];
        
      self.con = [NSURLConnection connectionWithRequest:request delegate:self];
        
    }else{
        // 暂停连接
        [self.con cancel];
    
    }
    
}
// 接收到响应
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    self.totalLength = response.expectedContentLength;
    // 如果有数据便不在创建新的文件
    if (self.currentLength > 0) {
        return;
    }
    NSFileManager *mgr = [NSFileManager defaultManager];
    // suggestFilename:就是取出响应头中 记录接收数据的名字(不是路径哦)
    self.toPath = [response.suggestedFilename cacheDir];
    NSLog(@"%@",self.toPath);
    [mgr createFileAtPath:self.toPath contents:nil attributes:nil];


}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // 数据流的模式,允许拼接。
    self.stream = [NSOutputStream outputStreamToFileAtPath:self.toPath append:YES];
    // 只有打开数据流,才能进行数据的拼接
    [self.stream open];
    
    // 数据流,接收byte数据 长度为:最大接收数据的长度,如果不这么设置的话,接收到的数据是有问题的。
    [self.stream write:data.bytes maxLength:data.length];
    // 设置数据长度
    self.currentLength += data.length;  
    self.progressView.progress = (float)1.0*self.currentLength / self.totalLength;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
     NSLog(@"%s",__func__);
// 必须和句柄一样 .关闭
    [self.stream close];
}

第四种:NSURLSession
NSURLSessionTask--->普通下载

  /**
     *  参数1、配置,一般为默认配置
     *  参数2、设置代理,谁成为它的代理 遵守协议[代理方法中接受数据]
     *  参数3、代理回调信息 到那个队列(线程)[一般为主队列]
     *  注意 子协议 继承与父协议, 遵守子协议, 就是遵守父协议
     */
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_02.png"];
// 创建人物,用于下载数据   
 NSURLSessionTask *task = [session dataTaskWithURL:url];
    [task resume];

代理方法对接收到的数据进行处理,遵守的协议是:NSURLSessionDataDelegate

#pragma mark - NSURLSessionDataDelegate
// 接收到响应
/**
 *  接收到响应时调用
 *
 *  @param session
 *  @param dataTask          触发事件的任务
 *  @param response          响应头
 *  @param completionHandler 回调(告诉我们如何接收(是否)数据)
 *    NSURLSessionResponseCancel = 0,   默认情况 为 取消 接收数据
 *    NSURLSessionResponseAllow = 1,    总是允许接收数据
 *    NSURLSessionResponseBecomeDownload = 2  成为下载时 才接收数据
 */
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
    //告诉系统,我们始终接收数据 
completionHandler(NSURLSessionResponseAllow);
  // 创建文件,用来接收数据
    NSFileManager *mgr = [NSFileManager defaultManager];
    
    NSString *toPath = [response.suggestedFilename cacheDir];
    self.toPath = toPath;
    NSLog(@"%@",toPath);
    [mgr createFileAtPath:toPath contents:nil attributes:nil];
  
}
// 输出流懒加载
- (NSOutputStream *)stream
{
    if (!_stream) {
        _stream = [NSOutputStream outputStreamToFileAtPath:self.toPath append:YES];
    }
    return _stream;

}
// 接收到数据
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
//这里我们直接用数据输出流来接受数据. 为了避免多次创建输出流,我们利用懒加载,对输出流进行处理
//    NSOutputStream *stream = [NSOutputStream outputStreamToFileAtPath:self.toPath append:YES];
//    
//    self.stream = stream;
    // 记住要打开数据流
    [self.stream open];
    [self.stream write:data.bytes maxLength:data.length];
}
// 接收完成
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
// 关闭输出流
    [self.stream close];
    self.stream = nil;
    // 接收完成 给空间赋值。
    NSData *data = [NSData dataWithContentsOfFile:self.toPath];
    UIImage *image = [UIImage imageWithData:data];
    self.imageView.image = image;
    
    NSLog(@"%s",__func__);
}

NSURLSessionTask可以实现更为简单的断点下载,苹果为我们提供了两个方法: 1.暂停suspend,2.开始resume
, 但调用suspend时, 任务会被暂停.当调用resume是,任务会从暂停的地方再次下载. 省去了NSURLConnection中请求头记录传入数据的麻烦.

在NSURLSession中提供了专门用于包装下载任务的类NSURLSessionDownloadTask----->普通下载

// 设置session会话,专门用来处理任务的执行
 NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_16.mp4"];
// 利用会话,创建下载任务 
    NSURLSessionDownloadTask *task = [session downloadTaskWithURL:url];
    // 对于不是block创建的任务,不会立即执行, 要调用resume
    [task resume];

代理方法的实现遵守的协议是:NSURLSessionDownloadDelegate----代理方法中会把接收完成的数据,存放在临时文件中, 我们需要将文件调出来,放在我们希望的位置location

#pragma mark - NSURLSessionDownloadDelegate
/**
 *  开始写入数据
 *
 *  @param session
 *  @param downloadTask              当前下载任务
 *  @param bytesWritten              当前这次写入数据的大小
 *  @param totalBytesWritten         已经写入数据的大小
 *  @param totalBytesExpectedToWrite 预计写入数据的总大小
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
    self.progressView.progress = (float)1.0*totalBytesWritten / totalBytesExpectedToWrite ;
}
/**
 *  恢复和暂停
 *
 *  @param session
 *  @param downloadTask       当前下载任务
 *  @param fileOffset         恢复之后又从文件的什么地方开始进行写入
 *  @param expectedTotalBytes 文件剩余总大小
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{
 NSLog(@"%s",__func__);
}
/**
 *  下载完成时
 *
 *  @param session
 *  @param downloadTask 当前下载任务 (属性中有响应头)
 *  @param location     下载的位置
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
    NSURLResponse *response = downloadTask.response;
    
    NSString *toPath = [response.suggestedFilename cacheDir];
    NSLog(@"%@",toPath);
    
    NSFileManager *mgr = [NSFileManager defaultManager];
    
    // 将保存的临时文件,转移到,指定目录
    [mgr moveItemAtURL:location toURL:[NSURL fileURLWithPath:toPath] error:nil];

}

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

}

NSURLSessionDownLoadTask--->断点下载的应用
NSURLSessionDownloadTask 为我们提供了新的断点下载的方法: cancelByProducingResumeData:void(^)(NSData *resumeData) 用于取消任务时,保存复原的数据,并记录当重新启动任务时,需要从何处继续加载 ---- 主要是用于暂停时数据的保留
dowmloadTaskWithResumeData:
必须在调用 resume才能开始任务
恢复下载时调用, 并且重新启动下载任务时 , 下载任务的起点已经发生了变化, 由传入的数据 开始启动任务---用于启动时,设置数据开始下载的起点

对于断点下载的优化------>对于每次启动程序, 我们并不需要重新下载, 只需要在本地沙盒中存储的数据--->继续下载就可以了

  1. 需要完成的就是, 发送请求的时候, 先读取本地数据, 并计算本地数据的大小, 然后在请求头设置时,加入请求数据开始范围
// 设置会话,并设置会话的代理, 以及回调队列
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
   
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_16.mp4"];
   
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
   // 通过本地文件得到,下载了多少数据。 一旦重新启动任务,会从多少数据开始。 但是一旦重启,数据的响应头 中期望数据长度,将会改变,改变量为已将下好的长度,与总长度只差
    self.fileSize = [self fileSizeWith:Name];
    NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.fileSize];
  // 设置请求头内容
    [request setValue:range forHTTPHeaderField:@"Range"];
   // 创建下载 
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
    self.task = task;
    [self.task resume];

2.创建方法,专门用于计算文件内容的大小

// 根据传入的文件名,来计算文件的大小
- (NSInteger)fileSizeWith:(NSString *)str;
{
    NSFileManager *mgr = [NSFileManager defaultManager];
    
    NSString *toPath = [str cacheDir];
// 文件中的相关参数
    NSDictionary *dict = [mgr attributesOfItemAtPath:toPath error:nil];
    
    return  [dict[NSFileSize] integerValue];
}

对于多次启动相同下载任务的优化(懒加载任务)

#define Name  @"minion_16.mp4"
@implementation ViewController
- (NSURLSessionDataTask *)task
{
    if (!_task) {
        NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
        
        NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_16.mp4"];
        
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
     
        self.fileSize = [self fileSizeWith:Name];
        NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.fileSize];
        
        [request setValue:range forHTTPHeaderField:@"Range"];
        
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
        self.task = task;

    }
    return _task;
}

Tools 工具类:

为了能更方便的进行下载内容存储,所以我们给下载文件到沙盒路径提供更为简单的方法, 外界调用最方便的方法.
对NSString添加分类,创建实现方法

// 传入字符串,直接在沙盒Cache中生成路径
- (instancetype)cacheDir
{
    NSString *cache = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
   return [cache stringByAppendingPathComponent:[self lastPathComponent]];
}
// 传入字符串,直接在沙盒Document中生成路径
- (instancetype)docDir
{

    NSString *doc = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES).firstObject;
    return [doc stringByAppendingPathComponent:[self lastPathComponent]];

}
// 传入字符串,直接在沙盒Temp中生成路径
- (instancetype)temDir
{

    NSString *tem = NSTemporaryDirectory();
    return [tem stringByAppendingPathComponent:[self lastPathComponent]];

}
上一篇下一篇

猜你喜欢

热点阅读