|
@@ -9,6 +9,16 @@
|
|
|
#import "mixDownloadManager.h"
|
|
|
#import "NSURLSession+mixDownloadTask.h"
|
|
|
|
|
|
+NSString * const mixDownloadCompleteNoti = @"mixDownloadCompleteNoti";
|
|
|
+
|
|
|
+@interface mixDownloadOperation ()
|
|
|
+{
|
|
|
+ mixReceiveResponseOperation _didReceiveResponseCallBack;
|
|
|
+ mixReceivDataOperation _didReceivDataCallBack;
|
|
|
+ mixCompleteOperation _didCompleteCallBack;
|
|
|
+}
|
|
|
+@end
|
|
|
+
|
|
|
@implementation mixDownloadOperation
|
|
|
- (instancetype)initWith:(NSString *)url session:(NSURLSession *)session {
|
|
|
|
|
@@ -57,6 +67,163 @@
|
|
|
return [fileInfo[NSFileSize] longLongValue];
|
|
|
}
|
|
|
|
|
|
+#pragma mark - mixDownloadOperationProtocol
|
|
|
+// 接收到相应时
|
|
|
+- (void)operateWithResponse:(NSURLResponse *)response {
|
|
|
+ // 总的size
|
|
|
+ if (self.currentSize + response.expectedContentLength == 0) {
|
|
|
+ HLog(@"下载数据回调异常");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ self.totalSize = self.currentSize + response.expectedContentLength;
|
|
|
+
|
|
|
+ // 创建空的文件夹
|
|
|
+ if (self.currentSize == 0) {
|
|
|
+ // 创建空的文件
|
|
|
+ [[NSFileManager defaultManager] createFileAtPath:self.fullPath contents:nil attributes:nil];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建文件句柄
|
|
|
+ self.handle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
|
|
|
+
|
|
|
+ // 文件句柄移动到文件末尾 位置 // 返回值是 unsign long long
|
|
|
+ [self.handle seekToEndOfFile];
|
|
|
+
|
|
|
+ // 开始下载记录文件下载信息
|
|
|
+ _downloadState = DownloadStateDoing;
|
|
|
+ [mixDownloadCacheManager saveFileInfoWithDict:[self downLoadInfoWithFinished:NO]];
|
|
|
+
|
|
|
+ // 回调给外界
|
|
|
+ if (_didReceiveResponseCallBack) {
|
|
|
+ dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
+ self->_didReceiveResponseCallBack(self.fullPath);
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (void)operateWithReceivingData:(NSData *)data {
|
|
|
+ // 获得已经下载的文件大小
|
|
|
+ self.currentSize += data.length;
|
|
|
+ HLog(@"currentSize:%lld---progress:%.2f", self.currentSize, 1.00*self.currentSize/self.totalSize);
|
|
|
+
|
|
|
+// long long hhhh = [self.handle seekToEndOfFile];
|
|
|
+// HLog(@"hhhh:%lld---handle:%@", hhhh, self.handle);
|
|
|
+
|
|
|
+ // 写入文件
|
|
|
+ [self.handle writeData:data];
|
|
|
+
|
|
|
+ // 下载状态 通知代理
|
|
|
+ if (_didReceivDataCallBack) {
|
|
|
+ dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
+ self->_didReceivDataCallBack((NSUInteger)self.currentSize,(NSUInteger)self.totalSize);
|
|
|
+
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 下载中通知
|
|
|
+ [self operationDoningWithOperation:self];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)operateWithComplete:(NSError *)error {
|
|
|
+ // 关闭文件句柄
|
|
|
+ [self.handle closeFile];
|
|
|
+ // 释放文件句柄
|
|
|
+ self.handle = nil;
|
|
|
+
|
|
|
+ // 完成下载 通知 block
|
|
|
+ if (error) {
|
|
|
+ [self completFailueWithError:error];
|
|
|
+ } else {
|
|
|
+ [self completCusesseWithCode:1];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (void)configCallBacksWithDidReceiveResponse:(mixReceiveResponseOperation)didReceiveResponse
|
|
|
+ didReceivData:(mixReceivDataOperation)didReceivData
|
|
|
+ didComplete:(mixCompleteOperation)didComplete {
|
|
|
+ _didReceiveResponseCallBack = didReceiveResponse;
|
|
|
+ _didReceivDataCallBack = didReceivData;
|
|
|
+ _didCompleteCallBack = didComplete;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark - operations
|
|
|
+/** 成功回调 1代表下载后成功回调 2代表直接从磁盘中获取了 */
|
|
|
+- (void)completCusesseWithCode:(NSInteger)code {
|
|
|
+ // 获取下载信息
|
|
|
+ NSDictionary *dict = [self downLoadInfoWithFinished:YES];
|
|
|
+
|
|
|
+
|
|
|
+ // 通知
|
|
|
+ [[NSNotificationCenter defaultCenter] postNotificationName:mixDownloadCompleteNoti object:self userInfo:dict];
|
|
|
+
|
|
|
+ if (code == 1) {
|
|
|
+ // 存储 文件下载信息
|
|
|
+ HLog(@"%zd", DownloadStateCompleted);
|
|
|
+ _downloadState = DownloadStateCompleted;
|
|
|
+ self.timeStamp = [iTools getNowTimeStamp];
|
|
|
+ [mixDownloadCacheManager saveFileInfoWithDict:dict];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 回到主线程 回调
|
|
|
+ if (_didCompleteCallBack) {
|
|
|
+ dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
+ self->_didCompleteCallBack(dict,nil);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 成功通知
|
|
|
+ [self operationSuccessWithOperation:self];
|
|
|
+}
|
|
|
+
|
|
|
+/** 失败回调 */
|
|
|
+- (void)completFailueWithError:(NSError *)error {
|
|
|
+
|
|
|
+ // 发通知
|
|
|
+ [[NSNotificationCenter defaultCenter] postNotificationName:mixDownloadCompleteNoti object:self userInfo:@{@"error":error}];
|
|
|
+ // 存储
|
|
|
+ _downloadState = DownloadStateFailed;
|
|
|
+ [mixDownloadCacheManager saveFileInfoWithDict:[self downLoadInfoWithFinished:NO]];
|
|
|
+
|
|
|
+ // 回调
|
|
|
+ if (_didCompleteCallBack) {
|
|
|
+ dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
+ self->_didCompleteCallBack(nil,error);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 失败通知
|
|
|
+ [self operationFailedWithOperation:self];
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+#pragma mark 发送通知
|
|
|
+// 失败某一个operation 保存本地 通知外界
|
|
|
+- (void)operationFailedWithOperation:(mixDownloadOperation *)operation {
|
|
|
+ HLog(@"SGDownloadTaskExeError");
|
|
|
+ operation.downloadState = DownloadStateFailed;
|
|
|
+ [mixDownloadCacheManager saveFileInfoWithDict:[operation downLoadInfoWithFinished:NO]];
|
|
|
+ [[NSNotificationCenter defaultCenter] postNotificationName:mixDownloadTaskExeError object:nil userInfo:@{@"operation" : operation}];
|
|
|
+}
|
|
|
+
|
|
|
+// 重启某一个operation 保存本地 通知外界
|
|
|
+- (void)operationDoningWithOperation:(mixDownloadOperation *)operation {
|
|
|
+ HLog(@"SGDownloadTaskExeing");
|
|
|
+// operation.downloadState = DownloadStateDoing; // 暂停之后 数据回来 状态会被修改为下载中 不科学
|
|
|
+ [mixDownloadCacheManager saveFileInfoWithDict:[operation downLoadInfoWithFinished:NO]];
|
|
|
+ [[NSNotificationCenter defaultCenter] postNotificationName:mixDownloadTaskExeing object:nil userInfo:@{@"operation" : operation}];
|
|
|
+}
|
|
|
+
|
|
|
+// 等待某一个operation 保存本地 通知外界
|
|
|
+- (void)operationSuccessWithOperation:(mixDownloadOperation *)operation {
|
|
|
+ HLog(@"SGDownloadTaskExeEnd");
|
|
|
+ operation.downloadState = DownloadStateCompleted;
|
|
|
+ [mixDownloadCacheManager saveFileInfoWithDict:[operation downLoadInfoWithFinished:YES]];
|
|
|
+ [[NSNotificationCenter defaultCenter] postNotificationName:mixDownloadTaskExeEnd object:nil userInfo:@{@"operation" : operation}];
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
#pragma mark - get download info
|
|
|
// 构造回调信息
|