浅谈iOS 断点续传

2017-05-27  本文已影响0人  爆裂少女小鸭子
项目需求

我们公司项目是APP和硬件相连,然后通过WI-FI,硬件做sever,取回硬件里我们想要取回的东西,所以我选择用断点续传

我用的断点续传,是网上大多数人都用的#import "MQLResumeManager.h" 大家可以谷歌一下,很多都有我就不一一赘述了 ,其实这篇文章,也只是我自己留着看的,因为网上写的比我好的挺多的,我只是想详细的研究一下封装好的代码
if (downloadedBytes > 0) {
//已经下载过,所以downloadedBytes=12345,Range: bytes=12345”表示请求资源开头 12345 字节之后的部分
        NSString *requestRange = [NSString stringWithFormat:@"bytes=%llu-", downloadedBytes];
        [request setValue:requestRange forHTTPHeaderField:@"Range"];
    }else{
//第一次下载没有已下载数据downloadedBytes为空
        int fileDescriptor = open([self.targetPath UTF8String], O_CREAT | O_EXCL | O_RDWR, 0666);
        if (fileDescriptor > 0) {
            close(fileDescriptor);
        }
    } ```

- 几个属性我们要先搞清楚
```@property (nonatomic, strong) NSURLSession *session;    //注意一个session只能有一个请求任务
@property (nonatomic, readwrite, retain) NSError *error; //请求出错
@property (nonatomic, readwrite, copy) completionBlock completionBlock;
@property (nonatomic, readwrite, copy) progressBlock progressBlock;
@property (nonatomic, strong) NSURL *url;           //文件资源地址
@property (nonatomic, strong) NSString *targetPath; //文件存放路径
@property long long totalContentLength;             //文件总大小
@property long long totalReceivedContentLength;     //已下载大小 ```

``` - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
    didReceiveData:(NSData *)data{
    //根据status code的不同,做相应的处理
    NSHTTPURLResponse *response = (NSHTTPURLResponse*)dataTask.response;
    if (response.statusCode == 200) {
        self.totalContentLength = dataTask.countOfBytesExpectedToReceive;
    }else if (response.statusCode == 206){
        NSString *contentRange = [response.allHeaderFields valueForKey:@"Content-Range"];
        if ([contentRange hasPrefix:@"bytes"]) {
//Content-Range: bytes 12367-200000/200000”说明了返回提供了请求资源所在的原始实体内的位置,还给出了整个资源的长度。
            NSArray *bytes = [contentRange componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" -/"]];
            if ([bytes count] == 4) {
//self.totalCotentLength=200000;
                self.totalContentLength = [[bytes objectAtIndex:3] longLongValue];
            }
        }
    }else if (response.statusCode == 416){
        NSString *contentRange = [response.allHeaderFields valueForKey:@"Content-Range"];
        if ([contentRange hasPrefix:@"bytes"]) {
            NSArray *bytes = [contentRange componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" -/"]];
            if ([bytes count] == 3) {
                self.totalContentLength = [[bytes objectAtIndex:2] longLongValue];
                if (self.totalReceivedContentLength == self.totalContentLength) {
                    //说明已下完
                    //更新进度
                    self.progressBlock();
                }else{
                    //416 Requested Range Not Satisfiable
                    self.error = [[NSError alloc]initWithDomain:[self.url absoluteString] code:416 userInfo:response.allHeaderFields];
                }
            }
        }
        return;
    }else{   
        //其他情况还没发现
        return;
    }  
    //向文件追加数据
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:self.targetPath];
    [fileHandle seekToEndOfFile]; //将节点跳到文件的末尾  
    [fileHandle writeData:data];//追加写入数据
    [fileHandle closeFile];
    //更新进度
    self.totalReceivedContentLength += data.length;
    self.progressBlock();
}```
- 206 Partial Content 客户发送了一个带有Range头的GET请求,服务器完成了它。 
- 416 Requested Range Not Satisfiable 服务器不能满足客户在请求中指定的Range头。 


上一篇下一篇

猜你喜欢

热点阅读