// // downloadManager.m // 隐私保护 // // Created by xd h on 2024/1/9. // #import "downloadManager.h" #import "cachesFileManager.h" #import #include @interface downloadManager () /**检测任务10s后 无反馈重新开始 */ @property (nonatomic, assign) NSInteger taskRenewTime; // @end @implementation downloadManager static downloadManager * cur_downloadManager = nil; +(downloadManager *)shareInstance; { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ cur_downloadManager = [[downloadManager alloc] init]; }); return cur_downloadManager; } - (id)init { self = [super init]; if (self) { //[self initManager]; } return self; } #pragma mark 读取数据库数据 - (void)getDataInDatabaseFun:(BOOL)isReGet complete:(custom_complete_Arr)complete { if(_databaseArr && _databaseArr.count == 3 && !isReGet){ complete(_databaseArr); return; } if(!_databaseArr) { _databaseArr = [NSMutableArray new]; } //KWeakSelf //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{ [couldPhoneFileModel bg_findAsync:download_tableName limit:0 orderBy:nil desc:NO complete:^(NSArray * _Nullable array) { NSMutableArray *failArr = [NSMutableArray new]; NSMutableArray *doneArr = [NSMutableArray new]; NSMutableArray *otherArr = [NSMutableArray new]; for (couldPhoneFileModel * curModel in array) { if(curModel.curDownloadStateType == downloadStateFail){ [failArr addObject:curModel]; } else if(curModel.curDownloadStateType == downloadStateDone){ [doneArr addObject:curModel]; } else{ [otherArr addObject:curModel]; } } NSLock *lock = [NSLock new]; [lock lock]; NSMutableArray *newArr = [NSMutableArray new]; [newArr addObject:otherArr]; [newArr addObject:doneArr]; [newArr addObject:failArr]; self->_databaseArr = newArr; [lock unlock]; complete(self->_databaseArr); }]; //}); } -(void)handleCouldPhoneFileModelToDownloadFileDataFunBy:(NSMutableArray*)indexPathsForSelectedItems complete:(custom_complete_Arr)complete { if(!indexPathsForSelectedItems && indexPathsForSelectedItems.count == 0){ complete(nil); return; } for (couldPhoneFileModel*model in indexPathsForSelectedItems) { model.bg_tableName = download_tableName; } _isNewAddTaskType = YES; KWeakSelf //查 [self getDataInDatabaseFun:YES complete:^(NSMutableArray * _Nonnull Arr) { //排重 NSMutableArray *newDownArr = [weakSelf checkDownloadTaskRepeatFun:indexPathsForSelectedItems]; if(newDownArr.count>0){ //存 [couldPhoneFileModel bg_saveOrUpdateArrayAsync:newDownArr complete:^(BOOL isSuccess) { //再查 [weakSelf getDataInDatabaseFun:YES complete:^(NSMutableArray * _Nonnull Arr) { complete(Arr); [weakSelf planToDownloadFileFun]; }]; }]; } else{ complete(Arr); [weakSelf planToDownloadFileFun]; } }]; } #pragma mark 检测是否有下载任务重复 - (NSMutableArray*)checkDownloadTaskRepeatFun:(NSMutableArray*)indexPathsForSelectedItems { if(!_databaseArr || _databaseArr.count != 3){ return indexPathsForSelectedItems; } NSMutableArray *downloadArr = _databaseArr[0]; NSMutableArray *newTaskArr = [NSMutableArray new]; for (couldPhoneFileModel*model in indexPathsForSelectedItems) { NSString *fileName = [model getFileNameFun]; BOOL isNeedAddType = YES; for (couldPhoneFileModel* hadModel in downloadArr) { NSString *hadFileName = [hadModel getFileNameFun]; if([fileName isEqualToString:hadFileName]){ isNeedAddType = NO; break; } } if(isNeedAddType){ [newTaskArr addObject:model]; } } return newTaskArr; } - (void)planToDownloadFileFun { if(!_databaseArr || _databaseArr.count != 3){ return; } _downLoadFileModelDataArr = _databaseArr[0]; [self beginDownloadFileFun]; } - (BOOL)checkFreeDiskSpaceInBytesIsOK:(long)fileByte{ struct statfs buf; unsigned long long freeSpace = -1; if (statfs("/var", &buf) >= 0) { freeSpace = (unsigned long long)(buf.f_bsize * buf.f_bavail); } long space = freeSpace - fileByte; if( space/fileByte < 2.0 || space < 500*1024*1024){ return NO; } return YES; } - (void)beginDownloadFileFun { if(_downLoadFileModelDataArr.count == 0) { _curDownloadFileModel = nil; [self didDownloadAllTaskDoneFun]; return; } self.taskRenewTime = [iTools getNowTimeStamp]; _isSuspendType = NO; _isDownloadIngType = YES; if(_reDownloadIngSelectIndex > 0 && _reDownloadIngSelectIndex < _downLoadFileModelDataArr.count){ _curDownloadFileModel = _downLoadFileModelDataArr[_reDownloadIngSelectIndex]; } else { _curDownloadFileModel = _downLoadFileModelDataArr.firstObject; } if(!_curDownloadFileModel){ return; } //做个异常处理 if(_databaseArr.count == 3 && _isNewAddTaskType){ NSMutableArray *downloadIngArr = _databaseArr[0]; if(_downLoadFileModelDataArr.count != downloadIngArr.count){ _databaseArr[0] = _downLoadFileModelDataArr; } } if(![self checkFreeDiskSpaceInBytesIsOK:_curDownloadFileModel.length]){ mainBlock(^{ [[iToast makeText:NSLocalizedString(@"phone_space_Insufficient",nil)] show]; }); return; } _curDownloadFileModel.curDownloadStateType = downloadStateUploading; [[NSNotificationCenter defaultCenter] postNotificationName:downloadFileBeginNotification object:_curDownloadFileModel]; } - (void)DownloadFileDoneOneFileFun { self.taskRenewTime = [iTools getNowTimeStamp]; _curDownloadFileModel.curDownloadStateType = downloadStateDone; // NSString *fileName = [_curDownloadFileModel getFileNameFun]; // [cachesFileManager removeItemAtPath:fileName type:DownLoadFileType error:nil]; [self DownloadFileChangeingOneFileFun]; if(_isSuspendType){ return; } [self beginDownloadFileFun]; } - (void)DownloadFileFailOneFileFun { self.taskRenewTime = [iTools getNowTimeStamp]; _curDownloadFileModel.curDownloadStateType = downloadStateFail; [self DownloadFileChangeingOneFileFun]; if(_isSuspendType){ return; } [self beginDownloadFileFun]; } - (void)DownloadFileChangeingOneFileFun { self.taskRenewTime = [iTools getNowTimeStamp]; if(_curDownloadFileModel.curDownloadStateType == downloadStateDone){ [_downLoadFileModelDataArr removeObject:_curDownloadFileModel]; [self handleDatabaseArrDeleteObjectInDownloading:_curDownloadFileModel]; [self handleDatabaseArrAddObjectInDone:_curDownloadFileModel]; } else if(_curDownloadFileModel.curDownloadStateType == uploadStateFail){ [_downLoadFileModelDataArr removeObject:_curDownloadFileModel]; [self handleDatabaseArrDeleteObjectInDownloading:_curDownloadFileModel]; [self handleDatabaseArrAddObjectInFail:_curDownloadFileModel]; } [_curDownloadFileModel bg_saveOrUpdateAsync:^(BOOL isSuccess) { //HLog(@"%@ 写入 %@", model.filename, isSuccess ? @"成功":@"失败"); }]; if(!_isSuspendType || _curDownloadFileModel.curDownloadStateType != uploadStateSuspend){ [[NSNotificationCenter defaultCenter] postNotificationName:downloadFileRefreshNotification object:_curDownloadFileModel]; } } - (void)handleDatabaseArrDeleteObjectInDownloading:(couldPhoneFileModel*)model { NSLock *lock = [NSLock new]; [lock lock]; if(_databaseArr && _databaseArr.count == 3 ){ NSMutableArray *ingArr = _databaseArr[0]; NSInteger count = ingArr.count; [ingArr removeObject:model]; NSInteger atferDelCount = ingArr.count; if(count == atferDelCount){ for (couldPhoneFileModel*preModel in ingArr) { if(preModel.bg_id.integerValue == model.bg_id.integerValue){ [ingArr removeObject:preModel]; break; } } } NSInteger atferDelCount2 = ingArr.count; if(count == atferDelCount2){ // HLog(@"\n\n\nerror:下载中的任务没有删除掉database bgid:%@\n\n\n\n",model.bg_id); } } [lock unlock]; } - (void)handleDatabaseArrAddObjectInDone:(couldPhoneFileModel*)model { NSLock *lock = [NSLock new]; [lock lock]; if(_databaseArr && _databaseArr.count == 3 ){ NSMutableArray *doneArr = _databaseArr[1]; [doneArr insertObject:model atIndex:0]; } [lock unlock]; } - (void)handleDatabaseArrAddObjectInFail:(couldPhoneFileModel*)model { NSLock *lock = [NSLock new]; [lock lock]; if(_databaseArr && _databaseArr.count == 3 ){ NSMutableArray *failArr = _databaseArr[2]; [failArr insertObject:model atIndex:0]; } [lock unlock]; } - (void)suspendDownloadFileFun:(BOOL)isSuspendAll { _isSuspendType = YES; if(isSuspendAll){ for (couldPhoneFileModel *couldPhoneFileMod in _downLoadFileModelDataArr) { couldPhoneFileMod.curDownloadStateType = downloadStateSuspend; } } } - (void)reDownloadFileFunBy:(NSMutableArray*)Arr withAll:(BOOL)isAllType { if(!_downLoadFileModelDataArr){ _downLoadFileModelDataArr = [NSMutableArray new]; } if(isAllType) { _isNewAddTaskType = YES; _downLoadFileModelDataArr = Arr; _reDownloadIngSelectIndex = -1; [self beginDownloadFileFun]; return; } _isNewAddTaskType = NO; _reDownloadIngSelectIndex = 0; NSMutableArray *curArr = [NSMutableArray arrayWithArray:Arr]; _downLoadFileModelDataArr = curArr; // for (uploadFileDataModel*addModel in Arr) { // // BOOL needAddModel = YES; // // for (int i=0;i< _downLoadFileModelDataArr.count;i++) // { // couldPhoneFileModel*preModel = _downLoadFileModelDataArr[i]; // // if(addModel.bg_id.integerValue == preModel.bg_id.integerValue) // { // needAddModel = NO; // // if(_reDownloadIngSelectIndex == 0){ // _reDownloadIngSelectIndex = i; // // if(i==0){ // _reDownloadIngSelectIndex = -1; // } // } // // break; // } // } // // if(needAddModel){ // [_downLoadFileModelDataArr addObject:addModel]; // _reDownloadIngSelectIndex = _downLoadFileModelDataArr.count -1; // } // } [self beginDownloadFileFun]; } - (void)handleDatabaseArrByDelete:(couldPhoneFileModel*)delModel { if(_databaseArr && _databaseArr.count == 3 ){ if(delModel.curDownloadStateType == downloadStateDone) { NSMutableArray *arr = _databaseArr[1]; [arr removeObject:delModel]; } else if(delModel.curDownloadStateType == downloadStateFail){ NSMutableArray *arr = _databaseArr[2]; [arr removeObject:delModel]; } else{ NSMutableArray *arr = _databaseArr[0]; [arr removeObject:delModel]; } } } - (void)deleteDownloadFileRecordBy:(NSMutableArray *)delArr withDelCache:(BOOL)isDelCache { //逻辑待优化 BOOL isSuc = false; BOOL isDelUploadingModel = false; NSMutableArray *curDelArr = [NSMutableArray arrayWithArray:delArr]; for (couldPhoneFileModel *couldPhoneFileMod in curDelArr) { NSMutableString* where = [[NSMutableString alloc] initWithString:@"where "]; NSString *curStr = [NSString stringWithFormat:@"%@=%@ ",bg_sqlKey(@"bg_id"),bg_sqlValue(couldPhoneFileMod.bg_id)]; [where appendString:curStr]; [couldPhoneFileModel bg_deleteAsync:download_tableName where:where complete:^(BOOL isSuccess) { }]; //isSuc = [couldPhoneFileModel bg_delete:download_tableName where:where]; [self handleDatabaseArrByDelete:couldPhoneFileMod]; if(couldPhoneFileMod.bg_id.integerValue == _curDownloadFileModel.bg_id.integerValue){ isDelUploadingModel = YES; [self suspendDownloadFileFun:NO]; } } if(isDelUploadingModel){ _isDownloadIngType = NO; if(_downLoadFileModelDataArr > 0){ [self beginDownloadFileFun]; } } [[NSNotificationCenter defaultCenter] postNotificationName:downloadFileRefreshNotification object:_curDownloadFileModel]; } //检查是否需要重新下载 - (void)checkReDownloadFileFun { if(!_curDownloadFileModel){ return; } if(_isSuspendType){ return; } NSInteger curTime = [iTools getNowTimeStamp]; if(self.taskRenewTime == 0){ return; } if(curTime - self.taskRenewTime < 10){ return; } if(![self checkFreeDiskSpaceInBytesIsOK:_curDownloadFileModel.length]){ mainBlock(^{ [[iToast makeText:NSLocalizedString(@"phone_space_Insufficient",nil)] show]; }); _curDownloadFileModel = nil; return; } [[NSNotificationCenter defaultCenter] postNotificationName:downloadFileBeginNotification object:_curDownloadFileModel]; } - (void)didDownloadAllTaskDoneFun { [[NSNotificationCenter defaultCenter] postNotificationName:downloadFileAllTaskDoneNotification object:nil]; } - (void)checkHadDownloadTaskWithComplete:(custom_complete_B)complete { [self getDataInDatabaseFun:NO complete:^(NSMutableArray * _Nonnull Arr) { mainBlock(^{ if(!Arr || Arr.count != 3){ complete(NO); } else{ NSArray *firstArr = Arr[0]; if(firstArr.count >0){ complete(YES); } else{ complete(NO); } } }); }]; } @end