//接收到服务器的响应
//这个方法只会调用一次
- (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(0, 0), ^{
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 currentRunLoop] run];
});
}
这时候下载进度会发生问题,因为断点续传服务器是将你暂停后剩下的数据返回,这时候,在获得的文件总的大小,是文件总大小-暂停数据的大小,所以总文件大小发生了改变,自然进度就出了问题,所以我们在下载开始前就要先获取文件总大小
- (IBAction)start:(id)sender {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self getTotalFile];
NSURL *url = [NSURL URLWithString:@"http://localhost/videos.zip"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
weakSelf.currentConnection = [NSURLConnection connectionWithRequest:request delegate:self];
[[NSRunLoop currentRunLoop] run];
});
}
- (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);
}