TUIMessageProgressManager.m 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. //
  2. // TUIMessageProgressManager.m
  3. // TUIChat
  4. //
  5. // Created by harvy on 2022/1/4.
  6. // Copyright © 2023 Tencent. All rights reserved.
  7. //
  8. #import "TUIMessageProgressManager.h"
  9. #import <ImSDK_Plus/ImSDK_Plus.h>
  10. @interface TUIMessageProgressManager () <V2TIMSDKListener>
  11. @property(nonatomic, strong) NSMutableDictionary<NSString *, NSNumber *> *uploadProgress;
  12. @property(nonatomic, strong) NSMutableDictionary<NSString *, NSNumber *> *dowonloadProgress;
  13. @property(nonatomic, strong) NSHashTable *delegates;
  14. @end
  15. @implementation TUIMessageProgressManager
  16. static id gShareInstance;
  17. + (instancetype)shareManager {
  18. static dispatch_once_t onceToken;
  19. dispatch_once(&onceToken, ^{
  20. gShareInstance = [[self alloc] init];
  21. });
  22. return gShareInstance;
  23. }
  24. - (instancetype)init {
  25. if (self = [super init]) {
  26. [V2TIMManager.sharedInstance addIMSDKListener:self];
  27. }
  28. return self;
  29. }
  30. - (void)addDelegate:(id<TUIMessageProgressManagerDelegate>)delegate {
  31. if (![NSThread isMainThread]) {
  32. __weak typeof(self) weakSelf = self;
  33. dispatch_async(dispatch_get_main_queue(), ^{
  34. [weakSelf addDelegate:delegate];
  35. });
  36. return;
  37. }
  38. if ([self.delegates containsObject:delegate]) {
  39. return;
  40. }
  41. [self.delegates addObject:delegate];
  42. }
  43. - (void)removeDelegate:(id<TUIMessageProgressManagerDelegate>)delegate {
  44. if (![NSThread isMainThread]) {
  45. __weak typeof(self) weakSelf = self;
  46. dispatch_async(dispatch_get_main_queue(), ^{
  47. [weakSelf removeDelegate:delegate];
  48. });
  49. return;
  50. }
  51. if ([self.delegates containsObject:delegate]) {
  52. [self.delegates removeObject:delegate];
  53. }
  54. }
  55. - (NSString *)getUploadIdentityForMessage:(V2TIMMessage *)message {
  56. NSString *msgID = message.msgID;
  57. if (message.elemType == V2TIM_ELEM_TYPE_VIDEO) {
  58. NSString *path = message.videoElem.videoPath;
  59. NSString *uuid = message.videoElem.videoUUID;
  60. return [msgID stringByAppendingString:message.videoElem.videoPath];
  61. } else if (message.elemType == V2TIM_ELEM_TYPE_IMAGE) {
  62. NSString *path = message.imageElem.path;
  63. return [msgID stringByAppendingString:message.imageElem.path];
  64. } else if (message.elemType == V2TIM_ELEM_TYPE_SOUND) {
  65. return [msgID stringByAppendingString:message.soundElem.path];
  66. }
  67. return msgID;
  68. }
  69. - (NSString *)getDownloadIdentityForMessage:(V2TIMMessage *)message {
  70. NSString *msgID = message.msgID;
  71. if (message.elemType == V2TIM_ELEM_TYPE_VIDEO) {
  72. NSString *uuid = message.videoElem.videoUUID;
  73. NSString *snapShotuuid = message.videoElem.snapshotUUID;
  74. return [msgID stringByAppendingString:uuid];
  75. } else if (message.elemType == V2TIM_ELEM_TYPE_IMAGE) {
  76. NSMutableArray<V2TIMImage *> *imageList = message.imageElem.imageList;
  77. for (V2TIMImage *img in imageList) {
  78. if (img.type == V2TIM_IMAGE_TYPE_ORIGIN) {
  79. NSString *url = img.url;
  80. }
  81. }
  82. return @"";
  83. }
  84. return @"";
  85. }
  86. - (void)uploadCallback:(NSString *)msgID {
  87. NSNumber *progress = @(100);
  88. if ([self.uploadProgress.allKeys containsObject:msgID]) {
  89. progress = [self.uploadProgress objectForKey:msgID];
  90. }
  91. for (id<TUIMessageProgressManagerDelegate> delegate in self.delegates) {
  92. if ([delegate respondsToSelector:@selector(onUploadProgress:progress:)]) {
  93. [delegate onUploadProgress:msgID progress:progress.integerValue];
  94. }
  95. }
  96. }
  97. - (void)appendUploadProgress:(NSString *)msgID progress:(NSInteger)progress {
  98. if (![NSThread isMainThread]) {
  99. __weak typeof(self) weakSelf = self;
  100. dispatch_async(dispatch_get_main_queue(), ^{
  101. [weakSelf appendUploadProgress:msgID progress:progress];
  102. });
  103. return;
  104. }
  105. if (msgID.length == 0) {
  106. return;
  107. }
  108. if ([self.uploadProgress.allKeys containsObject:msgID]) {
  109. [self.uploadProgress removeObjectForKey:msgID];
  110. }
  111. if (progress >= 100 || progress <= 0) {
  112. [self uploadCallback:msgID];
  113. return;
  114. }
  115. [self.uploadProgress setObject:@(progress) forKey:msgID];
  116. [self uploadCallback:msgID];
  117. }
  118. - (void)downloadCallback:(NSString *)msgID {
  119. NSNumber *progress = @(100);
  120. if ([self.dowonloadProgress.allKeys containsObject:msgID]) {
  121. progress = [self.dowonloadProgress objectForKey:msgID];
  122. }
  123. for (id<TUIMessageProgressManagerDelegate> delegate in self.delegates) {
  124. if ([delegate respondsToSelector:@selector(onDownloadProgress:progress:)]) {
  125. [delegate onDownloadProgress:msgID progress:progress.integerValue];
  126. }
  127. }
  128. }
  129. - (void)appendDownloadProgress:(NSString *)msgID progress:(NSInteger)progress {
  130. if (![NSThread isMainThread]) {
  131. __weak typeof(self) weakSelf = self;
  132. dispatch_async(dispatch_get_main_queue(), ^{
  133. [weakSelf appendDownloadProgress:msgID progress:progress];
  134. });
  135. return;
  136. }
  137. if (msgID.length == 0) {
  138. return;
  139. }
  140. if ([self.dowonloadProgress.allKeys containsObject:msgID]) {
  141. [self.dowonloadProgress removeObjectForKey:msgID];
  142. }
  143. if (progress >= 100 || progress <= 0) {
  144. [self downloadCallback:msgID];
  145. return;
  146. }
  147. [self.dowonloadProgress setObject:@(progress) forKey:msgID];
  148. [self downloadCallback:msgID];
  149. }
  150. - (void)notifyMessageSendingResult:(NSString *)msgID result:(TUIMessageSendingResultType)result {
  151. for (id<TUIMessageProgressManagerDelegate> delegate in self.delegates) {
  152. if ([delegate respondsToSelector:@selector(onMessageSendingResultChanged:messageID:)]) {
  153. [delegate onMessageSendingResultChanged:result messageID:msgID];
  154. }
  155. }
  156. }
  157. - (NSInteger)uploadProgressForMessage:(NSString *)msgID {
  158. if (![self.uploadProgress.allKeys containsObject:msgID]) {
  159. return 0;
  160. }
  161. NSInteger progress = 0;
  162. @synchronized(self) {
  163. progress = [[self.uploadProgress objectForKey:msgID] integerValue];
  164. }
  165. return progress;
  166. }
  167. - (NSInteger)downloadProgressForMessage:(NSString *)msgID {
  168. if (![self.dowonloadProgress.allKeys containsObject:msgID]) {
  169. return 0;
  170. }
  171. NSInteger progress = 0;
  172. @synchronized(self) {
  173. progress = [[self.dowonloadProgress objectForKey:msgID] integerValue];
  174. }
  175. return progress;
  176. }
  177. - (void)reset {
  178. if (![NSThread isMainThread]) {
  179. __weak typeof(self) weakSelf = self;
  180. dispatch_async(dispatch_get_main_queue(), ^{
  181. [weakSelf reset];
  182. });
  183. return;
  184. }
  185. [self.uploadProgress removeAllObjects];
  186. [self.dowonloadProgress removeAllObjects];
  187. }
  188. - (NSMutableDictionary<NSString *, NSNumber *> *)uploadProgress {
  189. if (_uploadProgress == nil) {
  190. _uploadProgress = [NSMutableDictionary dictionary];
  191. }
  192. return _uploadProgress;
  193. }
  194. - (NSMutableDictionary<NSString *, NSNumber *> *)dowonloadProgress {
  195. if (_dowonloadProgress == nil) {
  196. _dowonloadProgress = [NSMutableDictionary dictionary];
  197. }
  198. return _dowonloadProgress;
  199. }
  200. - (NSHashTable *)delegates {
  201. if (_delegates == nil) {
  202. _delegates = [NSHashTable weakObjectsHashTable];
  203. }
  204. return _delegates;
  205. }
  206. - (void)onConnecting {
  207. [self reset];
  208. }
  209. @end