美文网首页
浅谈iOS 断点续传

浅谈iOS 断点续传

作者: 爆裂少女小鸭子 | 来源:发表于2017-05-27 10:55 被阅读0次
    项目需求

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

    • 断点续传就是从文件上次中断的地方开始重新下载或上传数据,而不是从文件开头。(例如你上次下载到74%,断开连接了,重新连接它会从74%开始下载,不用从头开始,较适用于下载大型文件)
    • 断点续传主要依赖于HTTP头部定义的Range来完成的
    • 断点续传原理可以查看https://www.ibm.com/developerworks/cn/mobile/mo-cn-breakpoint/index.html 非常简单明了
    我用的断点续传,是网上大多数人都用的#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头。 
    
    
    

    相关文章

      网友评论

          本文标题:浅谈iOS 断点续传

          本文链接:https://www.haomeiwen.com/subject/sydxfxtx.html