多任务下载器组件

884 阅读2分钟

练习一个多任务下载器组件

搭建界面

截屏2021-03-14 下午4.06.50.png

  • 功能组件内容 截屏2021-03-14 下午4.08.35.png
  • WLFDownLoader :是下载组件,通过URL下载资源,同时把自己的下载的状态通过枚举记录下来,并可以通过block,返回出去,实现了数据的推模式和拉模式。
  • WLFDownLoaderManager : 是下载管理组件管理下载,当然多任务下载,就是通过这个创建多个downloader来下载
  • WLFFileTool : 文件管理工具。
  • NSString+SZ : 字符串转md5加密拓展类

WLFDownLoader

  • 必要属性
/** 下载会话 */
@property (nonatomic, strong) NSURLSession *session;
/** 文件输出流 */
@property (nonatomic, strong) NSOutputStream *outputStream;
/** 当前下载任务 */
@property (nonatomic, weak) NSURLSessionDataTask *dataTask;
  • 通过一系列的判断之后调用方法
    • 判断以及下载的文件是否存在
    • 判断当前缓存文件路径里的文件大小和资源的总大小进行判断是从0开始请求还是从目前缓存长度请求
  • 开始网络请求
- (void)downLoadWithURL:(NSURL *)url offset:(long long)offset {
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:0];
    // 通过控制range, 控制请求资源字节区间
    [request setValue:[NSString stringWithFormat:@"bytes=%lld-", offset] forHTTPHeaderField:@"Range"];
    // session 分配的task, 默认情况, 挂起状态
    self.dataTask = [self.session dataTaskWithRequest:request];
    [self resumeCurrentTask];

}
/**
 懒加载会话
 @return 会话
 */
- (NSURLSession *)session {
    if (!_session) {
        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
        _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    }
    return _session;
}
  • 代理方法响应
#pragma mark - 协议方法

/**
 第一次接受到相应的时候调用(响应头, 并没有具体的资源内容)
 通过这个方法, 里面, 系统提供的回调代码块, 可以控制, 是继续请求, 还是取消本次请求

 @param session 会话
 @param dataTask 任务
 @param response 响应头信息
 @param completionHandler 系统回调代码块, 通过它可以控制是否继续接收数据
 */
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler;

    // 取资源总大小
    // 1. 从  Content-Length 取出来
    // 2. 如果 Content-Range 有, 应该从Content-Range里面获取
    
    // 传递给外界 : 总大小 & 本地存储的文件路径
    // 比对本地大小, 和 总大小
    
        self.outputStream = [NSOutputStream outputStreamToFileAtPath:self.downLoadingPath append:YES];
     通过数据流的形式,开启数据通道,数据返回一些就写入一些到缓存中,这样就不用讲data放到内存中,防止APP内存激增奔溃。


/**
 当用户确定, 继续接受数据的时候调用

 @param session 会话
 @param dataTask 任务
 @param data 接受到的一段数据
 */
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data;

/**
 请求完成时候调用
 请求完成的时候调用( != 请求成功/失败)
 @param session 会话
 @param task 任务
 @param error 错误
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error;
  • 请求完成之后将临时文件写入到缓存文件中
  • 然后在加上一些block回调来显示请求的状态

demo

  • demo 之后等这个练习完成后一起上传