|
@@ -0,0 +1,321 @@
|
|
|
+//
|
|
|
+// CoursewareDownloadManager.m
|
|
|
+// GuanYueTeamTeacher
|
|
|
+//
|
|
|
+// Created by 王智 on 2023/1/10.
|
|
|
+//
|
|
|
+
|
|
|
+#import "CoursewareDownloadManager.h"
|
|
|
+#import "KnowledgePointListModel.h"
|
|
|
+
|
|
|
+@interface CoursewareDownloadManager ()
|
|
|
+
|
|
|
+@property (nonatomic, copy) CoursewareDownloadCallback callback;
|
|
|
+
|
|
|
+@property (nonatomic, strong) NSMutableArray *knowledgePointArray;
|
|
|
+
|
|
|
+@property (nonatomic, strong) NSMutableArray *undownloadFileArray;
|
|
|
+
|
|
|
+@property (nonatomic, assign) NSInteger currentSuccessIndex;
|
|
|
+
|
|
|
+@property (nonatomic, assign) NSInteger totalSouceCount;
|
|
|
+
|
|
|
+@property (nonatomic, copy) CoursewareCacheCallback cacheCallback;
|
|
|
+
|
|
|
+@property (nonatomic, copy) NSMutableDictionary *lessonCoursewareParm;
|
|
|
+
|
|
|
+@property (nonatomic, assign) float singleFileRate;
|
|
|
+
|
|
|
+@property (nonatomic, assign) BOOL isCancelDownload; // 是否取消下载
|
|
|
+
|
|
|
+@end
|
|
|
+
|
|
|
+@implementation CoursewareDownloadManager
|
|
|
+
|
|
|
++ (instancetype)shareInstance {
|
|
|
+ static CoursewareDownloadManager *manager = nil;
|
|
|
+ static dispatch_once_t onceToken;
|
|
|
+ dispatch_once(&onceToken, ^{
|
|
|
+ manager = [[CoursewareDownloadManager alloc] init];
|
|
|
+ });
|
|
|
+ return manager;
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark ---- 检测缓存
|
|
|
+- (void)checkCourseCacheStatus:(NSDictionary *)parm callback:(CoursewareCacheCallback)callback {
|
|
|
+ if (callback) {
|
|
|
+ self.cacheCallback = callback;
|
|
|
+ }
|
|
|
+ [self checkCacheWithParm:parm];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)checkCacheWithParm:(NSDictionary *)parm {
|
|
|
+ NSMutableDictionary *sendParm = [NSMutableDictionary dictionary];
|
|
|
+ [sendParm setValue:[parm ks_stringValueForKey:@"api"] forKey:@"api"];
|
|
|
+
|
|
|
+ NSMutableDictionary *content = [NSMutableDictionary dictionaryWithDictionary:[parm ks_dictionaryValueForKey:@"content"]];
|
|
|
+ NSMutableArray *courewareArray = [NSMutableArray arrayWithArray:[content ks_arrayValueForKey:@"data"]];
|
|
|
+ NSMutableArray *sourceArray = [NSMutableArray array];
|
|
|
+ for (NSDictionary *parm in courewareArray) {
|
|
|
+ NSArray *knowledgePointList = [parm ks_arrayValueForKey:@"knowledgePointList"];
|
|
|
+
|
|
|
+ NSMutableArray *listArray = [NSMutableArray array];
|
|
|
+ for (NSDictionary *sourceParm in knowledgePointList) {
|
|
|
+ KnowledgePointListModel *model = [[KnowledgePointListModel alloc] initWithDictionary:sourceParm];
|
|
|
+ [listArray addObject:model];
|
|
|
+ }
|
|
|
+ BOOL isCache = [self checkPointIsCache:listArray];
|
|
|
+ NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:parm];
|
|
|
+ [dic setValue:@(isCache) forKey:@"hasCache"];
|
|
|
+ [sourceArray addObject:dic];
|
|
|
+ }
|
|
|
+ [content setValue:sourceArray forKey:@"data"];
|
|
|
+ [sendParm setValue:content forKey:@"content"];
|
|
|
+
|
|
|
+ if (self.cacheCallback) {
|
|
|
+ self.cacheCallback(sendParm);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 判断当前课件是否缓存
|
|
|
+- (BOOL)checkPointIsCache:(NSArray *)listArray {
|
|
|
+
|
|
|
+ for (KnowledgePointListModel *model in listArray) {
|
|
|
+ for (MaterialList *listModel in model.materialList) {
|
|
|
+ if ([listModel.type isEqualToString:@"SONG"]) { // 曲目
|
|
|
+
|
|
|
+ }
|
|
|
+ else { // 下载图片和视频
|
|
|
+ NSString *url = listModel.content;
|
|
|
+ NSString *fileName = [url getUrlFileName];
|
|
|
+ if ([self isNomalFile:fileName]) {
|
|
|
+ fileName = [NSString stringWithFormat:@"%@%@%@", listModel.materialListIdentifier, [listModel.updateTime replaceAll:@" " WithString:@""],fileName];
|
|
|
+ NSString *filePath = [[self getCourewareSavePath] stringByAppendingPathComponent:fileName];
|
|
|
+ BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
|
|
|
+ if (isExist == NO) {
|
|
|
+ return NO;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return YES;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+#pragma mark ---- 下载
|
|
|
+- (void)downloadCourseWithParm:(NSDictionary *)parm callback:(CoursewareDownloadCallback)callback {
|
|
|
+ if (callback) {
|
|
|
+ self.callback = callback;
|
|
|
+ }
|
|
|
+ if (self.isDownloading) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ self.currentSuccessIndex = 0;
|
|
|
+ self.totalSouceCount = 0;
|
|
|
+ [self downloadCourseMessage:parm];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)downloadCourseMessage:(NSDictionary *)parm {
|
|
|
+ self.knowledgePointArray = [NSMutableArray array];
|
|
|
+ NSMutableDictionary *content = [NSMutableDictionary dictionaryWithDictionary:[parm ks_dictionaryValueForKey:@"content"]];
|
|
|
+ NSDictionary *coureParm = [content ks_dictionaryValueForKey:@"data"];
|
|
|
+ self.lessonCoursewareDetailId = [coureParm ks_stringValueForKey:@"lessonCoursewareDetailId"];
|
|
|
+ NSArray *sourceArray = [coureParm ks_arrayValueForKey:@"knowledgePointList"];
|
|
|
+ for (NSDictionary *parm in sourceArray) {
|
|
|
+ KnowledgePointListModel *model = [[KnowledgePointListModel alloc] initWithDictionary:parm];
|
|
|
+ [self.knowledgePointArray addObject:model];
|
|
|
+ }
|
|
|
+
|
|
|
+ [self checkCoursewareStatus];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)checkCoursewareStatus {
|
|
|
+
|
|
|
+ self.undownloadFileArray = [NSMutableArray array];
|
|
|
+ for (KnowledgePointListModel *model in self.knowledgePointArray) {
|
|
|
+ for (MaterialList *listModel in model.materialList) {
|
|
|
+ if ([listModel.type isEqualToString:@"SONG"]) { // 曲目
|
|
|
+
|
|
|
+ }
|
|
|
+ else { // 下载图片和视频
|
|
|
+ self.totalSouceCount++;
|
|
|
+ NSString *url = listModel.content;
|
|
|
+ NSString *fileName = [url getUrlFileName];
|
|
|
+ if ([self isNomalFile:fileName]) {
|
|
|
+ fileName = [NSString stringWithFormat:@"%@%@%@", listModel.materialListIdentifier, [listModel.updateTime replaceAll:@" " WithString:@""],fileName];
|
|
|
+ NSString *filePath = [[self getCourewareSavePath] stringByAppendingPathComponent:fileName];
|
|
|
+ BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
|
|
|
+ if (isExist == NO) {
|
|
|
+ [self.undownloadFileArray addObject:listModel];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ self.currentSuccessIndex = self.totalSouceCount - self.undownloadFileArray.count;
|
|
|
+ self.singleFileRate = 1.0 / self.totalSouceCount * 100;
|
|
|
+
|
|
|
+ [self downloadAllSourceFile];
|
|
|
+}
|
|
|
+
|
|
|
+- (BOOL)isNomalFile:(NSString *)fileName {
|
|
|
+ if ([fileName hasSuffix:@".png"] || [fileName hasSuffix:@".jpg"] || [fileName hasSuffix:@".jepg"] || [fileName hasSuffix:@".mp4"] || [fileName hasSuffix:@".flv"] || [fileName hasSuffix:@".avi"] || [fileName hasSuffix:@".mov"]) {
|
|
|
+ return YES;
|
|
|
+ }
|
|
|
+ return NO;
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark ---- 课件其他资源
|
|
|
+- (void)downloadAllSourceFile {
|
|
|
+ [self downloadFileIndex:0];
|
|
|
+}
|
|
|
+
|
|
|
+- (NSMutableDictionary *)configParmWithSource:(NSInteger)status progress:(NSInteger)progress {
|
|
|
+ NSMutableDictionary *sendParm = [NSMutableDictionary dictionary];
|
|
|
+ [sendParm setValue:@"downloadCoursewareToCache" forKey:@"api"];
|
|
|
+ NSMutableDictionary *content = [NSMutableDictionary dictionary];
|
|
|
+ [content setValue:@(status) forKey:@"downloadStatus"];
|
|
|
+ [content setValue:@(progress) forKey:@"progress"];
|
|
|
+ [content setValue:self.lessonCoursewareDetailId forKey:@"lessonCoursewareDetailId"];
|
|
|
+ [sendParm setValue:content forKey:@"content"];
|
|
|
+ return sendParm;
|
|
|
+}
|
|
|
+
|
|
|
+- (void)downloadFileIndex:(NSInteger)fileIndex {
|
|
|
+ if (self.isCancelDownload) {
|
|
|
+ self.isCancelDownload = NO;
|
|
|
+ self.isDownloading = NO;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (self.undownloadFileArray.count == 0) {
|
|
|
+ NSDictionary *parm = [self configParmWithSource:2 progress:100];
|
|
|
+ if (self.callback) {
|
|
|
+ self.callback(parm);
|
|
|
+ }
|
|
|
+ self.isDownloading = NO;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else if (fileIndex > self.undownloadFileArray.count - 1) {
|
|
|
+ if (self.callback) {
|
|
|
+ NSInteger rate = self.currentSuccessIndex * 100 / self.totalSouceCount;
|
|
|
+ if (self.undownloadFileArray.count == 0) {
|
|
|
+ rate = 100;
|
|
|
+ }
|
|
|
+ NSDictionary *parm = [self configParmWithSource:2 progress:rate];
|
|
|
+ if (self.callback) {
|
|
|
+ self.callback(parm);
|
|
|
+ }
|
|
|
+ self.isDownloading = NO;
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ self.isDownloading = YES;
|
|
|
+ MaterialList *model = self.undownloadFileArray[fileIndex];
|
|
|
+ NSString *url = model.content;
|
|
|
+ [KSNetworkingManager downloadFileRequestWithFileUrl:url progress:^(int64_t bytesRead, int64_t totalBytes) {
|
|
|
+ double progress = bytesRead * 1.0 / totalBytes;
|
|
|
+ NSLog(@"%f",progress);
|
|
|
+ NSInteger rate = (NSInteger) (progress * self.singleFileRate);
|
|
|
+ NSInteger preDownloadRate = self.currentSuccessIndex * 100 / self.totalSouceCount;
|
|
|
+ NSInteger totalRate = rate + preDownloadRate;
|
|
|
+ if (totalRate > 100) {
|
|
|
+ totalRate = 100;
|
|
|
+ }
|
|
|
+ NSDictionary *parm = [self configParmWithSource:1 progress:totalRate];
|
|
|
+ if (self.callback) {
|
|
|
+ self.callback(parm);
|
|
|
+ }
|
|
|
+ } success:^(NSURL * _Nonnull fileUrl) {
|
|
|
+ [self savePathWithLocalPath:[fileUrl resourceSpecifier] sourceModel:model fileIndex:fileIndex];
|
|
|
+
|
|
|
+ } faliure:^(NSError * _Nonnull error) {
|
|
|
+ NSInteger nextIndex = fileIndex + 1;
|
|
|
+ [self downloadFileIndex:nextIndex];
|
|
|
+ }];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)savePathWithLocalPath:(NSString *)localPath sourceModel:(MaterialList *)model fileIndex:(NSInteger)fileIndex {
|
|
|
+ NSString *url = model.content;
|
|
|
+ NSString *fileName = [NSString stringWithFormat:@"%@%@%@", model.materialListIdentifier, [model.updateTime replaceAll:@" " WithString:@""],[url getUrlFileName]];
|
|
|
+ NSString *filePath = [[self getCourewareSavePath] stringByAppendingPathComponent:fileName];
|
|
|
+ NSError *error;
|
|
|
+
|
|
|
+ BOOL isSuccess = [[NSFileManager defaultManager] moveItemAtPath:localPath toPath:filePath error:&error];
|
|
|
+ if (isSuccess) {
|
|
|
+ self.currentSuccessIndex++;
|
|
|
+ NSLog(@"rename success");
|
|
|
+ // 如果旧文件存在 就删除
|
|
|
+ if ([[NSFileManager defaultManager] fileExistsAtPath:localPath]) {
|
|
|
+ BOOL isDelSuccess = [[NSFileManager defaultManager] removeItemAtPath:localPath error:nil];
|
|
|
+ if (isDelSuccess) {
|
|
|
+ NSLog(@"remove success");
|
|
|
+ } else {
|
|
|
+ NSLog(@"remove fail");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (self.callback) {
|
|
|
+ NSInteger rate = self.currentSuccessIndex * 100 / self.totalSouceCount;
|
|
|
+ NSDictionary *parm = [self configParmWithSource:1 progress:rate];
|
|
|
+ if (self.callback) {
|
|
|
+ self.callback(parm);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ NSInteger nextIndex = fileIndex + 1;
|
|
|
+ [self downloadFileIndex:nextIndex];
|
|
|
+ }else{
|
|
|
+ NSLog(@"rename fail");
|
|
|
+ NSInteger nextIndex = fileIndex + 1;
|
|
|
+ [self downloadFileIndex:nextIndex];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (NSString *)getCourewareSavePath {
|
|
|
+ // 在Documents目录下创建一个名为CoursewarePath的文件夹
|
|
|
+ NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"CoursewarePath"];
|
|
|
+
|
|
|
+ NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
+ BOOL isDir = FALSE;
|
|
|
+ BOOL isDirExist = [fileManager fileExistsAtPath:path isDirectory:&isDir];
|
|
|
+ if(!(isDirExist && isDir)) {
|
|
|
+ BOOL bCreateDir = [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
|
|
|
+ if(!bCreateDir){
|
|
|
+ NSLog(@"创建文件夹失败!");
|
|
|
+ }
|
|
|
+// NSLog(@"创建文件夹成功,文件路径%@",path);
|
|
|
+ }
|
|
|
+ return path;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+- (NSString *)queryFileUrlWithParm:(NSDictionary *)parm {
|
|
|
+ NSString *locaPath = @"";
|
|
|
+ NSString *url = [parm ks_stringValueForKey:@"url"];
|
|
|
+ NSString *fileName = [NSString stringWithFormat:@"%@%@%@", [parm ks_stringValueForKey:@"materialId"], [[parm ks_stringValueForKey:@"updateTime"] replaceAll:@" " WithString:@""],[url getUrlFileName]];
|
|
|
+ locaPath = [[self getCourewareSavePath] stringByAppendingPathComponent:fileName];
|
|
|
+ BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:locaPath];
|
|
|
+ if (isExist) {
|
|
|
+ return locaPath;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return @"";
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (void)cancleDownloadCourseware {
|
|
|
+
|
|
|
+ self.isCancelDownload = YES;
|
|
|
+ [KSNetworkingManager cancelAllRequest];
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+#pragma mark --- lazying
|
|
|
+- (NSMutableArray *)knowledgePointArray {
|
|
|
+ if (!_knowledgePointArray) {
|
|
|
+ _knowledgePointArray = [NSMutableArray array];
|
|
|
+ }
|
|
|
+ return _knowledgePointArray;
|
|
|
+}
|
|
|
+
|
|
|
+@end
|