nasUploadManager.m 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. //
  2. // nasUploadManager.m
  3. // 双子星云手机
  4. //
  5. // Created by xd h on 2024/8/7.
  6. //
  7. #import "nasUploadManager.h"
  8. #import "AFNetworkReachabilityManager.h"
  9. #import "AFHTTPSessionManager.h"
  10. #import "frpUploadModel.h"
  11. @interface nasUploadManager ()
  12. @property(nonatomic,strong)AFHTTPSessionManager *uploadManager;
  13. @end
  14. @implementation nasUploadManager
  15. + (instancetype)shareInstance {
  16. static nasUploadManager *_instance;
  17. static dispatch_once_t onceToken;
  18. dispatch_once(&onceToken, ^{
  19. _instance = [[self alloc] init];
  20. });
  21. return _instance;
  22. }
  23. - (id)init
  24. {
  25. self = [super init];
  26. if (self) {
  27. [self initManager];
  28. }
  29. return self;
  30. }
  31. - (void)initManager
  32. {
  33. _uploadManager = [[AFHTTPSessionManager alloc] init];
  34. _uploadManager.requestSerializer = [AFJSONRequestSerializer serializer];
  35. _uploadManager.responseSerializer = [AFJSONResponseSerializer serializer];
  36. [_uploadManager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
  37. _uploadManager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/json", @"text/javascript",@"text/html",@"text/plain",nil];
  38. _uploadManager.requestSerializer.timeoutInterval = 180;
  39. }
  40. - (void)nasUploadFileToFileServiceWithParams:(NSMutableDictionary *)params model:(uploadFileDataModel*)dataModel data:(NSData *)data success:(netWork_Success)success faild:(netWork_Faild)faildStr {
  41. NSString *urlString = ksharedAppDelegate.NASFileByBoxService;
  42. urlString = [[NSString alloc] initWithFormat:@"%@uploadFile",urlString];
  43. NSInteger position = 0;
  44. if([[params allKeys] containsObject:@"position"]){
  45. NSNumber *positionNumber = params[@"position"];
  46. position = positionNumber.longValue;
  47. }
  48. HLog(@"上传地址:%@---%@---position:%ld--",urlString,params,position);
  49. [_uploadManager POST:urlString parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
  50. NSString *mimeType =@"application/octet-stream";
  51. if ([[params allKeys] containsObject:@"imageType"]) {
  52. mimeType = @"image/jpeg";
  53. }
  54. else if ([[params allKeys] containsObject:@"videoType"]) {
  55. mimeType = @"video/mp4";
  56. }
  57. [formData appendPartWithFileData:data name:@"file" fileName:params[@"filename"] mimeType:mimeType];
  58. } progress:^(NSProgress * _Nonnull uploadProgress) {
  59. HLog(@"上传 Progress:--%@---%lld",uploadProgress,uploadProgress.completedUnitCount)
  60. dataModel.didUploadBytes = position + (uploadProgress.completedUnitCount);
  61. [[NSNotificationCenter defaultCenter] postNotificationName:uploadFileRefreshNotification object:dataModel];
  62. } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
  63. success(responseObject);
  64. } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error, id _Nonnull responseObject) {
  65. faildStr(error);
  66. }];
  67. }
  68. - (void)beginUploadDataBy:(uploadFileDataModel*)dataModel success:(netWork_Success)success faild:(netWork_Faild)faildStr
  69. {
  70. NSMutableDictionary *paraDict = [NSMutableDictionary new];
  71. NSString* taskUid = [iTools getTaskUidStr];
  72. [paraDict setObject:taskUid forKey:@"taskId"];
  73. [paraDict setObject:@0 forKey:@"position"];
  74. [paraDict setObject:@1 forKey:@"isLast"];
  75. if(dataModel.savePath){
  76. [paraDict setObject:dataModel.savePath forKey:@"savePath"];
  77. }
  78. else{
  79. HLog(@"获取保存路径失败")
  80. return;
  81. }
  82. if(dataModel.filename){
  83. [paraDict setObject:dataModel.filename forKey:@"filename"];
  84. }
  85. else{
  86. HLog(@"获取用户名失败")
  87. return;
  88. }
  89. KWeakSelf
  90. if(dataModel.curUploadFileType == uploadFileTypeImage){
  91. [paraDict setObject:@1 forKey:@"imageType"];
  92. NSData *curData = dataModel.imageData;
  93. [self nasUploadFileToFileServiceWithParams:paraDict model:dataModel data:curData success:^(id _Nonnull responseObject) {
  94. HLog(@"%@上传完成",dataModel.filename)
  95. success(responseObject);
  96. } faild:^(NSError * _Nonnull error) {
  97. HLog(@"%@上传失败",dataModel.filename)
  98. faildStr(error);
  99. }];
  100. }
  101. else{
  102. [paraDict setObject:@1 forKey:@"videoType"];
  103. //断点续传处理 先传1字节数据看服务器是否有数据
  104. //NSData *videoData = [self cutVideoFileFunAtIndex:0 withMaxLenght:1 withModel:dataModel];
  105. //[paraDict setObject:@0 forKey:@"isLast"];
  106. NSData *videoData = [self cutVideoFileFunAtIndex:0 withMaxLenght:MaxNasUploadPieceSzie withModel:dataModel];
  107. // NSData *videoData = [self cutVideoFileFunAtIndex:0 withMaxLenght:MaxNasUploadPieceSzie withModel:dataModel];
  108. [self nasUploadFileToFileServiceWithParams:paraDict model:dataModel data:videoData success:^(id _Nonnull responseObject) {
  109. HLog(@"%@上传完成",dataModel.filename)
  110. success(responseObject);
  111. // frpUploadModel *model = [[frpUploadModel alloc] initWithDictionary:responseObject error:nil];
  112. // if(model && model.msg){
  113. // NSInteger curPosition = model.position > 0 ? model.position : 1;
  114. // [weakSelf beginUploadVideoDataFunBy:dataModel with:curPosition withPara:paraDict success:^(id _Nonnull responseObject) {
  115. // success(responseObject);
  116. // } faild:^(NSError * _Nonnull error) {
  117. // faildStr(error);
  118. // }];
  119. // }
  120. // else{
  121. // NSError *err = [NSError new];
  122. // faildStr(err);
  123. // }
  124. } faild:^(NSError * _Nonnull error) {
  125. HLog(@"%@上传失败",dataModel.filename)
  126. faildStr(error);
  127. }];
  128. }
  129. }
  130. - (void)beginUploadVideoDataFunBy:(uploadFileDataModel*)dataModel with:(NSInteger)position withPara:(NSMutableDictionary*)paraDict success:(netWork_Success)success faild:(netWork_Faild)faildStr
  131. {
  132. BOOL isLastPicece = NO;
  133. if((dataModel.totalBytes - position) <= MaxNasUploadPieceSzie){
  134. [paraDict setObject:@1 forKey:@"isLast"];
  135. isLastPicece = YES;
  136. }
  137. [paraDict setObject:[NSNumber numberWithLong:position] forKey:@"position"];
  138. //视频数据切片
  139. NSData *videoData = [self cutVideoFileFunAtIndex:position withMaxLenght:MaxNasUploadPieceSzie withModel:dataModel];
  140. KWeakSelf
  141. [self nasUploadFileToFileServiceWithParams:paraDict model:dataModel data:videoData success:^(id _Nonnull responseObject) {
  142. HLog(@"%@上传完成",dataModel.filename)
  143. frpUploadModel *model = [[frpUploadModel alloc] initWithDictionary:responseObject error:nil];
  144. if(model && model.msg){
  145. if (isLastPicece) {
  146. success(responseObject);
  147. }
  148. else{
  149. [weakSelf beginUploadVideoDataFunBy:dataModel with:(position +MaxNasUploadPieceSzie) withPara:paraDict success:^(id _Nonnull responseObject) {
  150. } faild:^(NSError * _Nonnull error) {
  151. NSError *err = [NSError new];
  152. faildStr(err);
  153. }];
  154. }
  155. }
  156. else{
  157. NSError *err = [NSError new];
  158. faildStr(err);
  159. }
  160. } faild:^(NSError * _Nonnull error) {
  161. HLog(@"%@上传失败---%@",dataModel.filename,error)
  162. faildStr(error);
  163. }];
  164. }
  165. #pragma mark 分段读视频文件
  166. -(NSData*)cutVideoFileFunAtIndex:(NSUInteger)dataIndex withMaxLenght:(NSInteger)maxLengt withModel:(uploadFileDataModel*)dataModel{
  167. NSString *filePath = [cachesFileManager getFilePathWithName:dataModel.filename type:uploadFileTypeVideo]; // 文件路径
  168. NSFileManager *manager0 = [NSFileManager defaultManager];
  169. if(![manager0 fileExistsAtPath:filePath]) {
  170. return [NSData new];
  171. }
  172. NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath]; // 创建文件句柄
  173. // 设置分段读取的大小,这里以每次读取1KB为例
  174. const NSUInteger chunkSize = maxLengt;//cutVideoPieceSzie;//5 * 1024 *1024;
  175. NSMutableData *data = [NSMutableData data];
  176. if (fileHandle) {
  177. long long endOfFile = [fileHandle seekToEndOfFile];
  178. if(dataModel.totalBytes == 0
  179. || dataModel.totalBytes < endOfFile){//异常处理
  180. dataModel.totalBytes = endOfFile;
  181. }
  182. //异常处理
  183. if(endOfFile == dataIndex){
  184. dataModel.totalBytes = endOfFile;
  185. dataModel.didUploadBytes = endOfFile;
  186. dataModel.curUploadStateType = uploadStateDone;
  187. [fileHandle closeFile];
  188. return data;
  189. }
  190. if (endOfFile >= chunkSize) {
  191. // 读取文件的分段数据到某个位置
  192. [fileHandle seekToFileOffset:dataIndex];
  193. // 读取文件的分段数据
  194. NSData* chunk = [fileHandle readDataOfLength:chunkSize];
  195. if (chunk) {
  196. [data appendData:chunk];
  197. }
  198. }
  199. else{
  200. // 读取文件的分段数据到某个位置
  201. [fileHandle seekToFileOffset:dataIndex];
  202. [data appendData:[fileHandle readDataToEndOfFile]];
  203. }
  204. // 在这里可以对文件内容进行处理
  205. // ...
  206. // 关闭文件句柄
  207. [fileHandle closeFile];
  208. }
  209. return data;
  210. }
  211. @end