标签:
主要是需要注意,在客服端发请求给服务器的时候,在请求头里是可以设置服务器返回的数据从哪开始,到哪结束的.
当服务器响应客户端时,是可以拿到服务器返回数据具体类型以及大小的
#import <Foundation/Foundation.h>
@interface ZYFileDownLoad : NSObject
//所需要下载文件的远程URL(连接服务器的路径)
@property (nonatomic, strong) NSString *urlStr;
//文件的存储路径
@property (nonatomic, strong) NSString *goalPath;
//是否正在下载
@property (nonatomic, readonly, getter= isDownLoading) BOOL downLoading;
//监听下载进度
@property (nonatomic, copy) void (^progressHandler)(double progress);
//下载完成后的回调
@property (nonatomic, copy) void (^finishHandler)();
//下载失败后的回调
@property (nonatomic, copy) void (^failureHandler)(NSError *error);
//开始下载
- (void)start;
//暂停下载
- (void)pause;
@end
/*
文件一般保存在下面的地址,Documents路径下的文件需要同步,文件大的话消耗性能,tmp路径下随时会被删除
所以一般保存在Library\Caches路径下
获取此路径:
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filepath = [caches stringByAppendingPathComponent:@"文件名.后缀名"];
*/
#import "ZYFileDownLoad.h"
@interface ZYFileDownLoad() <NSURLConnectionDataDelegate>
//当前已下载的数据长度
@property (nonatomic, assign) long long currentLength;
//连接对象
@property (nonatomic, strong) NSURLConnection *connection;
//总的文件长度
@property (nonatomic, assign) long long totalLength;
//写入文件句柄
@property (nonatomic, strong) NSFileHandle *writeHandle;
@end
@implementation ZYFileDownLoad
- (void)start
{
[self.urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:self.urlStr];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
//设置请求头信息,这里表示,此次数据范围是currentProgress 到文件最后(也就是只设置开头从什么地方下载)
NSString *value = [NSString stringWithFormat:@"bytes=%lld-",self.currentLength];
[request setValue:value forHTTPHeaderField:@"Range"];
self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
_downLoading = YES;
}
- (void)pause
{
[self.connection cancel];
self.connection = nil;
_downLoading = NO;
}
#pragma mark ----NSURLConnectionDataDelegate
//请求错误(失败)的时候调用
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
if (self.failureHandler) {
self.failureHandler(error);
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if (self.totalLength) return; //当已经回复过响应了,就无需再次回复(主要用于暂停下载,再回复下载操作)
//创建一个空的文件到沙盒中
NSFileManager *manager = [NSFileManager defaultManager];
[manager createFileAtPath:self.goalPath contents:nil attributes:nil];
////创建写数据的文件句柄
self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:self.goalPath];
//获得完整文件的长度(服务器响应客户端时,会返回具体具体的文件长度)
self.totalLength = response.expectedContentLength;
}
//当接受到服务器的数据就会调用(可能会被调用多次, 每次调用只会传递部分数据)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
self.currentLength += [data length]; //下载完成,累加长度
//进度
double progress = (double)self.currentLength / self.totalLength;
//通过block回调,可以执行block里面的操作
if (self.progressHandler) {
self.progressHandler(progress);
}
//移动文件尾部,往尾部追加数据
[self.writeHandle seekToEndOfFile];
[self.writeHandle writeData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//下载完毕,请客属性
self.currentLength = 0;
self.totalLength = 0;
if (self.currentLength == self.totalLength) {
//下载完毕,关闭连接
[self.writeHandle closeFile];
self.writeHandle = nil;
}
if (self.finishHandler) {
self.finishHandler();
}
}
@end
标签:
原文地址:http://www.cnblogs.com/ziyi--caolu/p/4674944.html