断点续传的实现原理

首先 按照正常的流程去实现选择正确的代理方法(协议要用NSURLConnectionDataDelegate)有一个特别类似的代理NSURLConnectionDownloadDelegate,不可以用这个,这个是苹果公司设计用来给一些杂志,读书类型应用的
选择以下三个代理方法

//接收到服务器的响应

//这个方法只会调用一次

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

//接收到服务器的数据

//这个方法会调用N次, 直到下载完成

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

//下载完成之后调用

- (void)connectionDidFinishLoading:(NSURLConnection *)connection


下载进度原理是:接收到的data的数据大小/总的文件的大小

首先考虑定义NSMutableData ,在接收数据的时候appendData,文件的总大小是response.expectedContentLength,定义一个long long 类型的属性去接收它,然后即可得到进度

因为NSMutableData不断的累加,必然造成内存暴涨的问题,所以不能用NSMutableData,换成NSOutputStream,使用outPutStream将数据写入沙盒中,要将outPutStream open下载完成后close。

下载这种延迟操作得放在子线程,所以开启子线程,发现代码不动了,这时候就把NSRunLoop run一下

继续的代码

- (IBAction)continue:(id)sender {

    

    dispatch_async(dispatch_get_global_queue(00), ^{

        NSURL *url = [NSURL URLWithString:@"http://localhost/videos.zip"];

        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

        NSString *value = [NSString stringWithFormat:@"bytes=%lld-",self.currentLength];

        [request setValue:value forHTTPHeaderField:@"Range"];

        self.currentConnection = [NSURLConnection connectionWithRequest:request delegate:self];

        

        [[NSRunLoop currentRunLooprun];

    });

}


这时候下载进度会发生问题,因为断点续传服务器是将你暂停后剩下的数据返回,这时候,在获得的文件总的大小,是文件总大小-暂停数据的大小,所以总文件大小发生了改变,自然进度就出了问题,所以我们在下载开始前就要先获取文件总大小

- (IBAction)start:(id)sender {

    

    __weak typeof(self) weakSelf = self;


    dispatch_async(dispatch_get_global_queue(00), ^{

        [self getTotalFile];

        

        NSURL *url = [NSURL URLWithString:@"http://localhost/videos.zip"];

        NSURLRequest *request = [NSURLRequest requestWithURL:url];

        

    weakSelf.currentConnection = [NSURLConnection connectionWithRequest:request delegate:self];

        

        [[NSRunLoop currentRunLooprun];

    });

}


- (void)getTotalFile{

    

    NSURL *url = [NSURL URLWithString:@"http://localhost/videos.zip"];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    request.HTTPMethod = @"HEAD";

    NSURLResponse *response = nil;

//    这里用到同步,因为只有在获取到文件的总大小后,你才能够进行下面的事情

   NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];

    NSLog(@"%zd",data.length);

    

    self.fileEndLength = response.expectedContentLength;

    NSLog(@"%lld",self.fileEndLength);


}

这里采用同步是因为只有获取到文件的总大小后,才去做下面的事情

你可能感兴趣的:(断点续传的实现原理)