// // CWFileUploadManager.m // uploadFileDemo // // Created by hyjet on 2018/3/9. // Copyright © 2018年 uploadFileDemo. All rights reserved. // #import "CWFileUploadManager.h" //#import "CWFileStreamSeparation.h" //#import "CWUploadTask.h" //#import "CWFileManager.h" //#define plistPath [[CWFileManager cachesDir] stringByAppendingPathComponent:uploadPlist] #define default_max @"uploadMax" @interface CWFileUploadManager () @property (nonatomic,strong)NSMutableDictionary *fileStreamDict; @property (nonatomic,strong)NSMutableDictionary *allTasks; //正在上传中的任务 @property (nonatomic,strong)NSMutableDictionary *uploadingTasks; //正在等待上传的任务 @property (nonatomic,strong)NSMutableDictionary *uploadWaitTasks; //已经上传完的任务 @property (nonatomic,strong)NSMutableDictionary *uploadEndTasks; @property (nonatomic,assign)NSInteger uploadMaxNum; @property (nonatomic,strong)NSURL *url; @property (nonatomic,strong)NSMutableURLRequest *request; @property (nonatomic,copy)NSString *uploadLocation; @end @implementation CWFileUploadManager static CWFileUploadManager * _instance; - (NSString *)getNewPlistPath { NSString *account = [HWDataManager getStringWithKey:Const_HWAccountPhoneNumber]; if (account.length != 0) { NSString *fileFolder = kPath_YunPan_Upload_Folder; return [fileFolder stringByAppendingPathComponent:@"uploadPlist.plist"]; }else { HLog(@"未登录 读取plist缓存文件失败!"); return @""; } } -(NSMutableDictionary *)fileStreamDict{ if (!_fileStreamDict) { _fileStreamDict = [NSMutableDictionary dictionary]; } return _fileStreamDict; } - (NSMutableDictionary *)allTasks { if (!_allTasks) { _allTasks = [_instance allUploadTasks]; } return _allTasks; } - (NSMutableDictionary *)uploadingTasks { return [self allUploadingTasks]; } - (NSMutableDictionary *)uploadWaitTasks { return [self allUploadWaitTasks]; } - (NSMutableDictionary *)uploadEndTasks { return [self allUploadEndTasks]; } + (instancetype)shardUploadManager { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; [_instance registeNotification]; [_instance defaultsTask]; _instance.plistPath = [_instance getNewPlistPath]; }); return _instance; } + (CWUploadTask *)startUploadWithPath:(NSString *)path { //是否是在册任务 if (![CWFileUploadManager isUploadTask:path]) { [_instance taskRecord:path]; } return [_instance continuePerformTaskWithFilePath:path]; } - (CWUploadTask *_Nullable)createUploadTask:(NSString *_Nonnull)filePath { //是否是在册任务 if (![CWFileUploadManager isUploadTask:filePath]) { [_instance taskRecord:filePath]; } return [self continuePerformTaskWithFilePath:filePath]; } - (CWUploadTask *_Nullable)createUploadTask:(NSString *_Nonnull)filePath uploadLocation:(NSString *_Nonnull)uploadLocation imageData:(NSData *_Nullable)imageData { //是否是在册任务 if (![CWFileUploadManager isUploadTask:filePath]) { [_instance taskRecord:filePath uploadLocation:uploadLocation imageData:imageData]; } return [self continuePerformTaskWithFilePath:filePath]; } //云手机上传 写入plist文件 - (void)createUploadTaskWithParams:(NSDictionary *)params { CWFileStreamSeparation *fileStream = [[CWFileStreamSeparation alloc] init]; NSString *path = [NSString stringWithFormat:@"%@", [params objectForKey:@"path"]]; fileStream.fileName = path.lastPathComponent; fileStream.fileSize = [[params objectForKey:@"length"] integerValue]; fileStream.uploadDateSize = [[params objectForKey:@"length"] integerValue]; fileStream.progressRate = 1.00; fileStream.bizId=[[NSUUID UUID] UUIDString]; fileStream.timeStamp = [iTools getNowTimeStamp]; fileStream.fileStatus = CWUploadStatusFinished; [self.fileStreamDict setObject:fileStream forKey:path.lastPathComponent]; CWUploadTask *uploadTask = self.allTasks[path.lastPathComponent]; if (!uploadTask) { uploadTask = [CWUploadTask initWithStreamModel:fileStream]; [self.allTasks setObject:uploadTask forKey:path.lastPathComponent]; } [self archerTheDictionary:_fileStreamDict file:self.plistPath]; HLog(@"%@---%@", self.fileStreamDict, self.allTasks); [[NSNotificationCenter defaultCenter] postNotificationName:CWUploadTaskExeEnd object:nil userInfo:@{@"fileStream":fileStream}]; } //配置全局默认的参数 - (void)config:(NSMutableURLRequest *)request maxTask:(NSInteger)num { if (!request.URL) { HLog(@"request缺少URL"); } [HWDataManager setIntegerWithKey:default_max value:num]; self.uploadMaxNum = 3; self.url = request.URL; self.request = request; } //设置最大任务数 - (void)setUploadMaxNum:(NSInteger)uploadMaxNum { if (_uploadMaxNum<3) { _uploadMaxNum = uploadMaxNum; }else if (_uploadMaxNum<0){ _uploadMaxNum = 3; }else if(_uploadMaxNum>=3){ _uploadMaxNum = 3; } } - (void)defaultsTask{ NSInteger tmpMax = [HWDataManager getIntegerWithKey:default_max]; self.uploadMaxNum = tmpMax?tmpMax:3; } /** 暂停一个上传任务 */ - (void)pauseUploadTask:(CWFileStreamSeparation *_Nonnull)fileStream { CWUploadTask *task = [self.allTasks objectForKey:fileStream.fileName]; [task taskCancel]; } /** 继续开始一个上传任务 */ - (void)resumeUploadTask:(CWFileStreamSeparation *_Nonnull)fileStream { CWUploadTask *task = [self.allTasks objectForKey:fileStream.fileName]; [task taskResume]; } /** 删除一个上传任务,同时会删除当前任务上传的缓存数据 */ - (void)removeUploadTask:(CWFileStreamSeparation *_Nonnull)fileStream { CWUploadTask *task = [self.allTasks objectForKey:fileStream.fileName]; [task taskCancel]; if ([[self.allTasks allKeys] containsObject:fileStream.fileName]) { [self.allTasks removeObjectForKey:fileStream.fileName]; } if ([[self.uploadingTasks allKeys] containsObject:fileStream.fileName]) { [self.uploadingTasks removeObjectForKey:fileStream.fileName]; } if (_fileStreamDict[fileStream.fileName]) { _fileStreamDict = [self unArcherThePlist:self.plistPath]; } [_fileStreamDict removeObjectForKey:fileStream.fileName]; [self archerTheDictionary:_fileStreamDict file:self.plistPath]; // 删除本地缓存的文件 NSString *fileFolder = kPath_YunPan_Upload_Folder; NSString *fileName = fileStream.fileName; NSString *fileURL = [fileFolder stringByAppendingPathComponent:fileName]; // HLog(@"%@--%@", fileURL, dict[@"fullPath"]); if ([CWFileManager isExistsAtPath:fileURL]) { BOOL flag = [[NSFileManager defaultManager] removeItemAtPath:fileURL error:nil]; HLog(@"上传文件删除结果:%d", flag); }else { HLog(@"上传文件删除失败 文件不存在"); } } /** 暂停所有的上传任务 */ - (void)pauseAllUploadTask { for (CWUploadTask *task in [self.allTasks allValues]) { [task taskCancel]; } } /** 启动所有上传任务 */ - (void)resumeAllUploadTask { if (self.allTasks.count == 0) { return; } NSMutableDictionary *dic = [NSMutableDictionary dictionary]; [self.allTasks enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { CWUploadTask *task = obj; if (task.fileStream.fileStatus == CWUploadStatusFinished || task.fileStream.progressRate == 1) { // 已完成的任务 HLog(@"该任务已完成---文件名:%@ 进度:%.2f 状态:%ld", task.fileStream.fileName, task.fileStream.progressRate, task.fileStream.fileStatus); }else { // 所有未完成任务 [dic setObject:task forKey:key]; [task taskResume]; } }]; // NSArray *array = [dic allValues]; // NSArray *sortDesc = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"timeStamp" ascending:YES]]; // NSArray *sortedArr = [array sortedArrayUsingDescriptors:sortDesc]; } /** 删除所有的上传任务 */ - (void)removeAllUploadTask { for (CWUploadTask *task in [self.allTasks allValues]) { [self removeUploadTask:task.fileStream]; } } /** 获取所有文件分片模型的上传任务字典 */ - (NSMutableDictionary*_Nullable)allUploadTasks { if (self.fileStreamDict.count == 0) { self.fileStreamDict = [self unArcherThePlist:self.plistPath]; } NSDictionary *tmpDict = _allTasks?_allTasks:@{}; NSMutableDictionary *fileWithTasks = [CWUploadTask uploadTasksWithDict:_instance.fileStreamDict]; [fileWithTasks addEntriesFromDictionary:tmpDict]; return fileWithTasks; } - (NSMutableDictionary*_Nullable)allUploadWaitTasks { NSMutableDictionary *dic = [NSMutableDictionary dictionary]; [self.allTasks enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { CWUploadTask *task = obj; if (task.fileStream.fileStatus == CWUploadStatusWaiting && task.fileStream.fileStatus != CWUploadStatusFailed) { [dic setObject:task forKey:key]; } }]; return dic; } - (NSMutableDictionary*_Nullable)allUploadEndTasks { NSMutableDictionary *dic = [NSMutableDictionary dictionary]; [self.uploadingTasks enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { CWUploadTask *task = obj; if (task.fileStream.fileStatus == CWUploadStatusFinished) { [dic setObject:task forKey:key]; } }]; return dic; } - (NSMutableDictionary*_Nullable)allUploadingTasks { NSMutableDictionary *dic = [NSMutableDictionary dictionary]; [self.allTasks enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { CWUploadTask *task = obj; if (task.fileStream.fileStatus == CWUploadStatusUpdownloading) { [dic setObject:task forKey:key]; } }]; return dic; } #pragma 工具方法 - (CWUploadTask *)continuePerformTaskWithFilePath:(NSString *)path{ //获取任务数据字段 CWFileStreamSeparation *fstream = [self.fileStreamDict objectForKey:path.lastPathComponent]; CWUploadTask *uploadTask = self.allTasks[path.lastPathComponent]; if (!uploadTask) { uploadTask = [CWUploadTask initWithStreamModel:fstream]; [self.allTasks setObject:uploadTask forKey:path.lastPathComponent]; } // [uploadTask taskResume]; return uploadTask; } + (BOOL)isUploadTask:(NSString *)path{ _instance = [CWFileUploadManager shardUploadManager]; if (![CWFileManager isFileAtPath:_instance.plistPath]) { [CWFileManager createFileAtPath:_instance.plistPath overwrite:NO]; } _instance.fileStreamDict = [_instance unArcherThePlist:_instance.plistPath]; if (_instance.fileStreamDict[path.lastPathComponent] == nil) { return NO; }else{ return YES; } } //新建任务分片模型并存入plist文件 - (CWFileStreamSeparation * _Nullable)taskRecord:(NSString *)path{ CWFileStreamSeparation *file = [[CWFileStreamSeparation alloc] initFileOperationAtPath:path forReadOperation:YES]; [self.fileStreamDict setObject:file forKey:path.lastPathComponent]; [self archerTheDictionary:_fileStreamDict file:self.plistPath]; return file; } //新建任务分片模型并存入plist文件 - (CWFileStreamSeparation * _Nullable)taskRecord:(NSString *)path uploadLocation:(NSString *)uploadLocation imageData:(NSData *)imageData { CWFileStreamSeparation *file = [[CWFileStreamSeparation alloc] initFileOperationAtPath:path forReadOperation:YES uploadLocation:uploadLocation imageData:imageData]; [self.fileStreamDict setObject:file forKey:path.lastPathComponent]; [self archerTheDictionary:_fileStreamDict file:self.plistPath]; return file; } #pragma mark - notification - (void)registeNotification{ HLog(@"del 2024525 暂未做"); /* hxd del 2024525 暂未做 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskExeEnd:) name:CWUploadTaskExeEnd object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskExeSuspend:) name:CWUploadTaskExeSuspend object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskExeError:) name:CWUploadTaskExeError object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(accountChange) name:ChangeAccountNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exchanggeAccount) name:ExchangeLoginAccountNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exchanggeAccount) name:AccountLoginOutsideNotification object:nil]; */ } //app启动或者app从后台进入前台都会调用这个方法 - (void)applicationBecomeActive{ [self uploadingTasksItemExe]; } - (void)taskExeSuspend:(NSNotification *)notification { CWFileStreamSeparation *fs = notification.userInfo.allValues.firstObject; [self.uploadingTasks removeObjectForKey:fs.fileName]; [self.allTasks enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { CWUploadTask *task = obj; if (task.fileStream.fileStatus == CWUploadStatusWaiting && self.uploadingTasks.allValues.count < self.uploadMaxNum) { [[CWFileUploadManager shardUploadManager] resumeUploadTask:task.fileStream]; } }]; [self allUploadingTasks]; } - (void)taskExeEnd:(NSNotification *)notification { CWFileStreamSeparation *fs = notification.userInfo.allValues.firstObject; [self.uploadingTasks removeObjectForKey:fs.fileName]; [self.uploadWaitTasks enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { CWUploadTask *task = obj; if (self.uploadingTasks.allValues.count < self.uploadMaxNum) { [task taskResume]; }else{ *stop = YES; } }]; [self allUploadingTasks]; } - (void)taskExeError:(NSNotification *)notification { CWFileStreamSeparation *fs = notification.userInfo[@"fileStream"]; NSError *error = (NSError *)notification.userInfo[@"error"]; [self.uploadingTasks removeObjectForKey:fs.fileName]; HLog(@"taskError:%@",error); } - (void)uploadingTasksItemExe{ NSDictionary *dict = [NSDictionary dictionaryWithDictionary:self.uploadingTasks]; [self.uploadingTasks removeAllObjects]; [dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { CWUploadTask *task = obj; [task taskResume]; }]; [self.uploadWaitTasks enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { CWUploadTask *task = obj; if (self.uploadingTasks.allValues.count