简易下载器

简易下载器
  1. 边播边下载
  2. 断点续传
  3. 删除数据库文件
下载功能的实现

先创建classes文件夹
1.机制 沙盒路径lib(cache perferme) document tmp 一般存在cache中

  1. 下载中与下载完成的区别是文件大小的区别 (文件总大小的本地记录) 通过文件目录进行分类 在tmp中的是未完成的 在cache中的是完成下载的
    MD5 url 作为名称防止重复资源

1.1 告诉外界下载完毕,并且传递相关信息
1.2 检测临时文件是否存在 以当前的存在文件大小 作为开始字节 去网络请求资源 本地大小如果大于总大小就删除本地临时缓存 从零开始下载
2.2 不存在 从零字节开始请求资源

容错处理

下载路径

tmp存放临时下载文件
cache存放下载完成的文件
判断下载的总数据大小与临时文件比较 开始请求数据

下载流程

使用HEAD方法请求总下载量

可以通过其他方式获取总大小 所以可以省略
//    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//    request.HTTPMethod = @"HEAD";
//    NSURLResponse *response;
//    NSError *error;
//    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
//    if (error == nil) {
//        long long totalSize = response.expectedContentLength;
//        NSLog(@"%lld", vtotalSize);
//    }

1.创建下载请求
session需要设为全局变量

@property (nonatomic, strong) NSURLSession *session;

 NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:0];  [request setValue:[NSString stringWithFormat:@"bytes=%lld-", offset] forHTTPHeaderField:@"Range"];
//    session分配的任务默认是挂起的
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
    [dataTask resume];

NSURLSessionDataDelegate
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler

1.第一次接受到 只包含请求头
2.可以通过block 取消本次请求 NSURLSessionResponseCancel
3.通过allHead中的 Content-Range="bytes 0-10/11" 获取总大小 或者Content-Length获取总大小
4.缓存有问题删除缓存并重新下载 下载完成就取消

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data

直接用Data 会造成内存问题 使用NSOutputStream来进行

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error

1.验证文件完整性 包括文件大小和文件MD5
2.关闭output流

@property (nonatomic,weak) NSURLSessionDataTask * dataTask;

使用weak引用dataTask
为下载器添加 暂停 取消 和删除文件功能

下载状态改变

对download进行封装 开始下载,当任务存在继续下载
如果调用了几次暂停 就要调用几次继续 才能继续

推模式 内部状态改变主动发送信息 block 代理 通知
拉模式 state 只要保证外部每次访问这个属性 都是正确的值 通过set方法

通过状态来控制多次点击和取消
外部不断读取内部timer的状态变化

下载的事件传递

封装为block函数调用

typedef void (^DownLoadInfoType)(long long totalSize);
typedef void (^StateChangeType)( XMGDownLoadState state);
typedef void (^ProgressBlockType)(float progress);
typedef void (^SuccessBlockType)(NSString *cachePath);
typedef void (^FailedBlockType)();
-(void)downLoader:(NSURL *)url downLoadInfo:(DownLoadInfoType)downLoadInfo state:(StateChangeType)stateChange progress:(ProgressBlockType)progressBlock success:(SuccessBlockType)successBlock fail:(FailedBlockType)failBlock;

多任务下载

使用manager的字典管理 单例对象
MD5转换

- (NSString *)md5Str {
    
    const char *data = self.UTF8String;
    
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
//    把C语言字符串 转为 md5 c 字符串
    CC_MD5(data, (CC_LONG)strlen(data), digest);
    
    NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i ++) {
        [result appendFormat:@"%02x", digest[i]];
    }
    
    return result;
    
}

可以通过MD5文件内容作为文件名
控制任务数

你可能感兴趣的:(简易下载器)