WFCUMediaMessageDownloader.m 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. //
  2. // MediaMessageDownloader.m
  3. // WildFireChat
  4. //
  5. // Created by heavyrain lee on 2018/8/29.
  6. // Copyright © 2018 WildFireChat. All rights reserved.
  7. //
  8. #import "WFCUMediaMessageDownloader.h"
  9. #import "AFNetworking.h"
  10. static WFCUMediaMessageDownloader *sharedSingleton = nil;
  11. @interface WFCUMediaMessageDownloader()
  12. @property(nonatomic, strong)NSMutableDictionary<NSString*, NSNumber*> *downloadingMessages;
  13. @end
  14. @implementation WFCUMediaMessageDownloader
  15. + (instancetype)sharedDownloader {
  16. if (sharedSingleton == nil) {
  17. @synchronized (self) {
  18. if (sharedSingleton == nil) {
  19. sharedSingleton = [[WFCUMediaMessageDownloader alloc] init];
  20. sharedSingleton.downloadingMessages = [[NSMutableDictionary alloc] init];
  21. }
  22. }
  23. }
  24. return sharedSingleton;
  25. }
  26. - (void)downloadFileWithURL:(NSString*)requestURLString
  27. parameters:(NSDictionary *)parameters
  28. savedPath:(NSString*)savedPath
  29. downloadSuccess:(void (^)(NSURLResponse *response, NSURL *filePath))success
  30. downloadFailure:(void (^)(NSError *error))failure
  31. downloadProgress:(void (^)(NSProgress *downloadProgress))progress
  32. {
  33. AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
  34. NSMutableURLRequest *request =[serializer requestWithMethod:@"GET" URLString:requestURLString parameters:parameters error:nil];
  35. NSURLSessionDownloadTask *task = [[AFHTTPSessionManager manager] downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
  36. progress(downloadProgress);
  37. } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
  38. return [NSURL fileURLWithPath:savedPath];
  39. } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
  40. if(error){
  41. failure(error);
  42. }else{
  43. success(response,filePath);
  44. }
  45. }];
  46. [task resume];
  47. }
  48. - (BOOL)tryDownload:(WFCCMessage *)msg
  49. success:(void(^)(long long messageUid, NSString *localPath))successBlock
  50. error:(void(^)(long long messageUid, int error_code))errorBlock {
  51. long long messageUid = msg.messageUid;
  52. if (!messageUid) {
  53. NSLog(@"Error, try download message have invalid uid");
  54. errorBlock(0, -2);
  55. return TRUE;
  56. }
  57. if (![msg.content isKindOfClass:[WFCCMediaMessageContent class]]) {
  58. NSLog(@"Error, try download message with id %lld, but it's not media message", messageUid);
  59. errorBlock(msg.messageUid, -1);
  60. return TRUE;
  61. }
  62. WFCCMediaMessageContent *mediaContent = (WFCCMediaMessageContent *)msg.content;
  63. if (mediaContent.localPath.length) {
  64. successBlock(msg.messageUid, mediaContent.localPath);
  65. return TRUE;
  66. }
  67. NSFileManager *fileManager = [NSFileManager defaultManager];
  68. BOOL isDir;
  69. NSError *error = nil;
  70. NSString *downloadDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject stringByAppendingString:@"/download"];
  71. if (![fileManager fileExistsAtPath:downloadDir isDirectory:&isDir]) {
  72. if(![fileManager createDirectoryAtPath:downloadDir withIntermediateDirectories:YES attributes:nil error:&error]) {
  73. errorBlock(msg.messageUid, -1);
  74. NSLog(@"Error, create download folder error");
  75. return YES;
  76. }
  77. if (error) {
  78. errorBlock(msg.messageUid, -1);
  79. NSLog(@"Error, create download folder error:%@", error);
  80. return YES;
  81. }
  82. }
  83. if (!isDir) {
  84. errorBlock(msg.messageUid, -1);
  85. NSLog(@"Error, create download folder error");
  86. return YES;
  87. }
  88. //通知UI开始显示下载动画
  89. [[NSNotificationCenter defaultCenter] postNotificationName:kMediaMessageStartDownloading object:@(messageUid)];
  90. if (self.downloadingMessages[mediaContent.remoteUrl]) {
  91. return NO;
  92. }
  93. NSString *savedPath = [downloadDir stringByAppendingPathComponent:[NSString stringWithFormat:@"media_%ld", mediaContent.remoteUrl.hash]];
  94. if ([mediaContent isKindOfClass:[WFCCSoundMessageContent class]]) {
  95. savedPath = [NSString stringWithFormat:@"%@.wav", savedPath];
  96. } else if([mediaContent isKindOfClass:[WFCCVideoMessageContent class]]) {
  97. savedPath = [NSString stringWithFormat:@"%@.mp4", savedPath];
  98. } else if([mediaContent isKindOfClass:[WFCCImageMessageContent class]]) {
  99. savedPath = [NSString stringWithFormat:@"%@.jpg", savedPath];
  100. } else if([mediaContent isKindOfClass:[WFCCFileMessageContent class]]) {
  101. WFCCFileMessageContent *content = (WFCCFileMessageContent *)mediaContent;
  102. savedPath = [downloadDir stringByAppendingPathComponent:[NSString stringWithFormat:@"%ld-%@", mediaContent.remoteUrl.hash, content.name]];
  103. }
  104. if ([fileManager fileExistsAtPath:savedPath]) {
  105. mediaContent.localPath = savedPath;
  106. [[WFCCIMService sharedWFCIMService] updateMessage:messageUid content:mediaContent];
  107. successBlock(msg.messageUid, savedPath);
  108. [[NSNotificationCenter defaultCenter] postNotificationName:kMediaMessageDownloadFinished object:@(messageUid) userInfo:@{@"result":@(YES), @"localPath":savedPath}];
  109. return YES;
  110. }
  111. [self.downloadingMessages setObject:@(messageUid) forKey:mediaContent.remoteUrl];
  112. [self downloadFileWithURL:mediaContent.remoteUrl parameters:nil savedPath:savedPath downloadSuccess:^(NSURLResponse *response, NSURL *filePath) {
  113. NSLog(@"download message content of %lld success", messageUid);
  114. dispatch_async(dispatch_get_main_queue(), ^{
  115. [[WFCUMediaMessageDownloader sharedDownloader].downloadingMessages removeObjectForKey:mediaContent.remoteUrl];
  116. WFCCMessage *newMsg = msg;
  117. if (msg.conversation.type != Chatroom_Type) {
  118. newMsg = [[WFCCIMService sharedWFCIMService] getMessageByUid:messageUid];
  119. }
  120. if (!newMsg) {
  121. NSLog(@"Error, message %lld not exist", messageUid);
  122. errorBlock(msg.messageUid, -1);
  123. return;
  124. }
  125. if (![newMsg.content isKindOfClass:[WFCCMediaMessageContent class]]) {
  126. NSLog(@"Error, message %lld not media message", messageUid);
  127. errorBlock(msg.messageUid, -1);
  128. return;
  129. }
  130. WFCCMediaMessageContent *newContent = (WFCCMediaMessageContent *)newMsg.content;
  131. newContent.localPath = filePath.absoluteString;
  132. [[WFCCIMService sharedWFCIMService] updateMessage:newMsg.messageId content:newContent];
  133. mediaContent.localPath = filePath.absoluteString;
  134. successBlock(newMsg.messageUid, filePath.absoluteString);
  135. [[NSNotificationCenter defaultCenter] postNotificationName:kMediaMessageDownloadFinished object:@(messageUid) userInfo:@{@"result":@(YES), @"localPath":filePath.absoluteString}];
  136. });
  137. } downloadFailure:^(NSError *error) {
  138. dispatch_async(dispatch_get_main_queue(), ^{
  139. [[WFCUMediaMessageDownloader sharedDownloader].downloadingMessages removeObjectForKey:mediaContent.remoteUrl];
  140. errorBlock(msg.messageUid, -1);
  141. [[NSNotificationCenter defaultCenter] postNotificationName:kMediaMessageDownloadFinished object:@(messageUid) userInfo:@{@"result":@(NO)}];
  142. });
  143. NSLog(@"download message content of %lld failure with error %@", messageUid, error);
  144. } downloadProgress:^(NSProgress *downloadProgress) {
  145. NSLog(@"总大小:%lld,当前大小:%lld",downloadProgress.totalUnitCount,downloadProgress.completedUnitCount);
  146. }];
  147. return YES;
  148. }
  149. - (void)dealloc {
  150. [[NSNotificationCenter defaultCenter] removeObserver:self];
  151. }
  152. @end