123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573 |
- //
- // 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<NSString*,CWUploadTask*>*_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<NSString*,CWUploadTask*>*_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<NSString*,CWUploadTask*>*_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<NSString*,CWUploadTask*>*_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<self.uploadMaxNum) {
- [task taskResume];
- }else{
- *stop = YES;
- }
- }];
- [self allUploadingTasks];
- }
- - (void)accountChange { // 修改账号
- self.plistPath = [self getNewPlistPath];
- }
- - (void)exchanggeAccount { // 切换账号
- HLog(@"切换账号");
-
- [self pauseAllUploadTask]; // 暂停所有上传任务
-
- self.plistPath = [self getNewPlistPath];
- [self.allTasks removeAllObjects];
- self.allTasks = nil;
- [self.fileStreamDict removeAllObjects];
- [self clearCookies];
- }
- // 清空Cookie
- - (void)clearCookies {
-
- NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
- NSArray *cookieArray = [NSArray arrayWithArray:[cookieJar cookies]];
- for(id obj in cookieArray)
- {
- [cookieJar deleteCookie:obj];
- }
- }
- #pragma mark - tools
- //归档
- - (void)archerTheDictionary:(NSDictionary *)dict file:(NSString *)path{
- [HWDataManager archiveObject:dict toPlistPath:path];
- }
- //解档
- - (NSMutableDictionary *)unArcherThePlist:(NSString *)path{
- NSMutableDictionary *dic = [HWDataManager readObjectFromPlistPath:path];
- return dic;
- }
- #pragma mark - 相册文件写入Cache
- /// 将相册里的视频文件缓存到Cache
- - (NSString *_Nullable)writeVideoDataFromURL:(NSURL *_Nullable)url uploadLocation:(NSString *_Nullable)uploadLocation {
-
- NSString *account = [HWDataManager getStringWithKey:Const_HWAccountPhoneNumber];
- if (account.length != 0) {
- NSString *fileFolder = kPath_YunPan_Upload_Folder;
- NSString *originalPath = [url.absoluteString stringByReplacingOccurrencesOfString:@"file://" withString:@""];
- NSString *fileName;
- // fileName = [NSString stringWithFormat:@"%@/%@", uploadLocation,fileName];
- fileName = [NSString stringWithFormat:@"%@", [iTools getNowTimeStampString]];
-
- NSString *videoName = [NSString stringWithFormat:@"SZX%@.mp4", fileName];
- NSString *sandboxPath = [fileFolder stringByAppendingPathComponent:videoName];
- NSError * error = nil;
- BOOL isSuccess = [CWFileManager moveItemAtPath:originalPath toPath:sandboxPath overwrite:YES error:&error];
- HLog(@"保存相册视频文件:%@到Caches:%@是否成功:%d error:%@", originalPath, sandboxPath,isSuccess,error);
- return sandboxPath;
- }else {
- HLog(@"未登录 缓存视频文件失败!");
- return nil;
- }
-
- }
- /// 将相册里的图片文件缓存到Cache
- - (NSString *_Nullable)writeIamgeData:(NSData *_Nullable)data iamgeName:(NSString *_Nullable)iamgeName uploadLocation:(NSString *_Nullable)uploadLocation {
- NSString *account = [HWDataManager getStringWithKey:Const_HWAccountPhoneNumber];
- if (account.length != 0) {
- NSString *fileFolder = kPath_YunPan_Upload_Folder;
- NSString *fileName = [NSString stringWithFormat:@"SZX%@", [iTools getNowTimeStampString]];
-
- NSString *videoName = [NSString stringWithFormat:@"%@.PNG", fileName];
- NSString *sandboxPath = [fileFolder stringByAppendingPathComponent:videoName];
- BOOL isSuccess = [data writeToFile:sandboxPath atomically:YES];
- HLog(@"保存相册图片文件到Caches是否成功:%d", isSuccess);
- return sandboxPath;
- }else {
- HLog(@"未登录 缓存图片文件失败!");
- return nil;
- }
- }
- - (NSString *_Nullable)writeIamgeDataToLocal:(NSData *_Nullable)data {
- NSString *account = [HWDataManager getStringWithKey:Const_HWAccountPhoneNumber];
- if (account.length != 0) {
- NSString *fileFolder = kPath_YunPan_Upload_Folder;
- NSString *fileName = [NSString stringWithFormat:@"SZX%@", [iTools getNowTimeStampString]];
-
- NSString *videoName = [NSString stringWithFormat:@"%@.PNG", fileName];
- NSString *sandboxPath = [fileFolder stringByAppendingPathComponent:videoName];
- BOOL isSuccess = [data writeToFile:sandboxPath atomically:YES];
- HLog(@"保存相册图片文件到Caches是否成功:%d", isSuccess);
- return sandboxPath;
- }else {
- HLog(@"未登录 缓存图片文件失败!");
- return nil;
- }
- }
- @end
|