<h6>因為本人是個巨懶無比赶么,最近我在尋找一個下載的第三方庫隘击,可是找了半天木有很完美的,所以只能自己動手寫箱锐,雖然很懶得寫但是為了活命比勉,還是努力的動手了。</h6>
<h5>我更新了代碼之前寫的有些問題驹止,也太丑了浩聋,我要對得起老爺們...
先不廢話,首先隊列控制還木有完全實現(xiàn)臊恋,因為最近工作比較忙衣洁,所以老爺們有問題給我留言就好啦,大家一起討論抖仅,但是多任務下載坊夫,獲取下載進度砖第,獲取下載速度,暫停繼續(xù)都已經OK了环凿。下面是調用梧兼,先看看是不是各位老爺們要的。
[[LBCDownLoadManager shredManager]downLoad:URL
fileName:@"你下載任務的名字如:蒼老師.avi"
progress:^(CGFloat progress, NSString *sizeString, NSString *speedString) {
NSLog(@"下載進度: %f",progress);
NSLog(@"%@",sizeString);
NSLog(@"下載速度: %@",speedString);
} success:^(NSString *filePath) {
} failure:^(NSError *error) {
}];
<h6>第一個參數就是下載的URL 第二個為你下載文件的文件名智听,然后返回參數老爺們自己看吧羽杰,你們這么聰明就不用我介紹了,再往下是成功后返回文件路徑到推。拿到后你們可以隨意做你們想做的事情了考赛,失敗后會有error,這里說下环肘,暫停也會走failure這個block,所以大家需要判斷下集灌,稍候我會完善下悔雹。或者老爺們自己動手完善下也可以欣喧。
<h5>接下來說下思路吧腌零,我用的是NSURLSessionDataTask
來實現(xiàn)的斷點下載。
<h6>首先獲得NSURLSession對象并且
<NSURLSessionTaskDelegate>
遵守這個代理協(xié)議
-(NSURLSession *)LBCSession{
if (!_LBCSession) {
//創(chuàng)建config對象
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
//創(chuàng)建session對象唆阿,并添加到主隊列中,當然各位老爺也可以不添加到主隊列.
_LBCSession = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];
}
return _LBCSession;
}
<h6>思路是這樣的益涧,取得
URLString
也就是下載的URL的哈希值作為當前任務的唯一標識,在做好下載準備的時候我會在本地沙盒中創(chuàng)建一個plist文件驯鳖,存儲已經開始下載文件的已下載大小闲询,key為URLString
的哈希,這樣如果下載過程中斷開網絡浅辙,等下次連接到網絡的時候我也知道這次我下載了多少扭弧,再從上次斷開的地方接著下載就OK了
#pragma mark - 下載方法
/**
* 斷點下載
*
* @param urlString 下載的鏈接
* @param destinationPath 下載的文件的保存路徑
* @param process 下載過程中回調的代碼塊,會多次調用
* @param completion 下載完成回調的代碼塊
* @param failure 下載失敗的回調代碼塊
*/
-(void)downloadWithUrlString:(NSString *)urlString toFileName:(NSString *)fileName process:(ProcessHandle)process completion:(CompletionHandle)completion failure:(FailureHandle)failure{
if(urlString&&fileName)
{
self.url_string=urlString;
_fileName=fileName;
_process=process;
_completion=completion;
_failure=failure;
//判斷是否已經下載完成
if ([self getAllLength:urlString.hash]==[self getFileDownloadedLength:urlString.hash]&&[self getFileDownloadedLength:urlString.hash]>0) {
if (completion) {
completion();
}
if (process) {
process(1.0,[self filesSize:urlString],@"0kb/s");
}
return;
}
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
// 設置請求頭
NSString *range = [NSString stringWithFormat:@"bytes=%zd-", [self getFileDownloadedLength:urlString.hash]];
[request setValue:range forHTTPHeaderField:@"Range"];
// 創(chuàng)建一個Data任務
NSURLSessionDataTask *task = [self.LBCSession dataTaskWithRequest:request];
// 設置下載任務的唯一標示
[task setValue:@(urlString.hash) forKeyPath:@"taskIdentifier"];
LBCDownLoadModel *lbc_download = [[LBCDownLoadModel alloc]init];
lbc_download.task = task;
lbc_download.fileName = fileName;
lbc_download.ProcessHandle = process;
lbc_download.CompetionHandle = completion;
lbc_download.FailureHandle = failure;
[self.downloadDic setValue:lbc_download forKey:@(urlString.hash).stringValue];
[task resume];
}
}
從
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URLString]];
建立請求開始為正式創(chuàng)建下載任務记舆,上面為判斷的是否已經下載和任務繼續(xù)暫停鸽捻。
上述代碼中的URLString.hash
為url的哈希值,去這個哈希值為的是做唯一標示泽腮,在多任務處理數據時可以根據唯一標識來判斷是哪個任務御蒲。
<h5>接下來為NSURLSessionDataTask
的代理方法
#pragma mark Delegate
// 收到響應
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)
response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
LBCDownLoadModel *lbc_Model = [self.downloadDic valueForKey:@(dataTask.taskIdentifier).stringValue];
NSUInteger allLength = response.expectedContentLength + [self getFileDownloadedLength:dataTask.taskIdentifier];
[self setAllLength:allLength WithTag:dataTask.taskIdentifier];
NSString *fullPath = [self createCachePath:dataTask.taskIdentifier];
// 創(chuàng)建流
NSOutputStream *stream = [NSOutputStream outputStreamToFileAtPath:fullPath append:YES];
lbc_Model.stream = stream;
lbc_Model.allLength = allLength;
[lbc_Model.stream open];
completionHandler(NSURLSessionResponseAllow);
}
// 接受數據(會多次調用)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
LBCDownLoadModel *lbc_Model = [self.downloadDic valueForKey:@(dataTask.taskIdentifier).stringValue];
if (lbc_Model) {
if (lbc_Model.stateBlock) {
lbc_Model.stateBlock(LBCDownloadStateRunning);
}
[lbc_Model.stream write:data.bytes maxLength:data.length];
CGFloat scale = (double)[self getFileDownloadedLength:dataTask.taskIdentifier] / lbc_Model.allLength;
if (lbc_Model.progressBlock) {
//計算網速
NSString *speedString=@"0.00Kb/s";
NSString *growString=[LBCDownLoad convertSize:_growth];
speedString=[NSString stringWithFormat:@"%@/s",growString];
lbc_Model.progressBlock(scale,[self getFileDownloadedLength:dataTask.taskIdentifier],speedString);
}
}
}
然后是計算下載速度,其實很簡單诊赊,就是用當前這一秒的下載數據大小減去前一秒的下載數據大小厚满,就是下載速度啦
- (instancetype)init
{
self = [super init];
if (self) {
_timer=[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(getGrowthSize) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
}
return self;
}
-(void)getGrowthSize
{
NSInteger size=[self getFileDownloadedLength:self.url.hash];
_growth=size-_lastSize;
_lastSize=size;
}
代碼在這里
https://github.com/gx921016/LBCoreNet.git