NIMSessionDataSourceImpl.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. //
  2. // NIMSessionTableData.m
  3. // NIMKit
  4. //
  5. // Created by chris on 2016/11/7.
  6. // Copyright © 2016年 NetEase. All rights reserved.
  7. //
  8. #import "NIMSessionDataSourceImpl.h"
  9. #import "NIMSessionMsgDatasource.h"
  10. @interface NIMSessionDataSourceImpl()
  11. @property (nonatomic,strong) NIMSession *session;
  12. @property (nonatomic,strong) NIMSessionMsgDatasource *dataSource;
  13. @property (nonatomic,strong) NSMutableArray *pendingMessages; //缓存的插入消息,聊天室需要在另外个线程计算高度,减少UI刷新
  14. @property (nonatomic,strong) id<NIMSessionConfig> sessionConfig;
  15. @end
  16. @implementation NIMSessionDataSourceImpl
  17. - (instancetype)initWithSession:(NIMSession *)session
  18. config:(id<NIMSessionConfig>)sessionConfig
  19. {
  20. self = [super init];
  21. if (self) {
  22. _session = session;
  23. _sessionConfig = sessionConfig;
  24. _pendingMessages = [[NSMutableArray alloc] init];
  25. _dataSource = [[NIMSessionMsgDatasource alloc] initWithSession:_session config:_sessionConfig];
  26. }
  27. return self;
  28. }
  29. - (NSArray *)items
  30. {
  31. return self.dataSource.items;
  32. }
  33. - (NIMSessionMessageOperateResult *)addMessageModels:(NSArray *)models
  34. {
  35. NSArray *indexpaths = [self.dataSource appendMessageModels:models];
  36. NIMSessionMessageOperateResult *result = [[NIMSessionMessageOperateResult alloc] init];
  37. result.indexpaths = indexpaths;
  38. result.messageModels = models;
  39. return result;
  40. }
  41. - (NIMSessionMessageOperateResult *)insertMessageModels:(NSArray *)models
  42. {
  43. NSArray *indexpaths = [self.dataSource insertMessageModels:models];
  44. NIMSessionMessageOperateResult *result = [[NIMSessionMessageOperateResult alloc] init];
  45. result.indexpaths = indexpaths;
  46. result.messageModels = models;
  47. return result;
  48. }
  49. - (NIMSessionMessageOperateResult *)deleteMessageModel:(NIMMessageModel *)model
  50. {
  51. NSArray *indexs = [self.dataSource deleteMessageModel:model];
  52. NIMSessionMessageOperateResult *result = [[NIMSessionMessageOperateResult alloc] init];
  53. NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
  54. for (NSNumber *index in indexs) {
  55. NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index.integerValue inSection:0];
  56. [indexPaths addObject:indexPath];
  57. }
  58. result.indexpaths = indexPaths;
  59. result.messageModels = @[model];
  60. return result;
  61. }
  62. - (NIMSessionMessageOperateResult *)updateMessageModel:(NIMMessageModel *)model
  63. {
  64. NSInteger index = [self.dataSource indexAtModelArray:model];
  65. [[self.dataSource items] replaceObjectAtIndex:index withObject:model];
  66. NIMSessionMessageOperateResult *result = [[NIMSessionMessageOperateResult alloc] init];
  67. NSIndexPath *indexpath = [NSIndexPath indexPathForRow:index inSection:0];
  68. result.indexpaths = @[indexpath];
  69. result.messageModels = @[model];
  70. return result;
  71. }
  72. - (NSInteger)indexAtModelArray:(NIMMessageModel *)model
  73. {
  74. return [self.dataSource indexAtModelArray:model];
  75. }
  76. - (NSArray *)deleteModels:(NSRange)range
  77. {
  78. return [self.dataSource deleteModels:range];
  79. }
  80. - (NIMMessageModel *)findModel:(NIMMessage *)message{
  81. NIMMessageModel *model;
  82. for (NIMMessageModel *item in self.dataSource.items.reverseObjectEnumerator.allObjects) {
  83. if ([item isKindOfClass:[NIMMessageModel class]] && [item.message.messageId isEqual:message.messageId]) {
  84. model = item;
  85. //防止那种进了会话又退出去再进来这种行为,防止SDK里回调上来的message和会话持有的message不是一个,导致刷界面刷跪了的情况
  86. model.message = message;
  87. }
  88. }
  89. return model;
  90. }
  91. - (void)cleanCache
  92. {
  93. [self.dataSource cleanCache];
  94. }
  95. - (void)resetMessages:(void(^)(NSError *error))handler{
  96. [self.dataSource resetMessages:handler];
  97. }
  98. - (void)loadHistoryMessagesWithComplete:(void(^)(NSInteger index, NSArray *messages , NSError *error))handler{
  99. [self.dataSource loadHistoryMessagesWithComplete:handler];
  100. }
  101. - (void)loadNewMessagesWithComplete:(void (^)(NSInteger, NSArray *, NSError *))handler {
  102. [self.dataSource loadPullUpMessagesWithComplete:handler];
  103. }
  104. - (void)checkAttachmentState:(NSArray *)messages{
  105. NSArray *items = [NSArray arrayWithArray:messages];
  106. for (id item in items) {
  107. NIMMessage *message;
  108. if ([item isKindOfClass:[NIMMessage class]]) {
  109. message = item;
  110. }
  111. if ([item isKindOfClass:[NIMMessageModel class]]) {
  112. message = [(NIMMessageModel *)item message];
  113. }
  114. if (message && !message.isOutgoingMsg
  115. && message.attachmentDownloadState == NIMMessageAttachmentDownloadStateNeedDownload
  116. && message.messageType != NIMMessageTypeFile)
  117. {
  118. [[NIMSDK sharedSDK].chatManager fetchMessageAttachment:message error:nil];
  119. }
  120. }
  121. }
  122. - (NSDictionary *)checkReceipts:(NSArray<NIMMessageReceipt *> *)receipts
  123. {
  124. if (self.session.sessionType == NIMSessionTypeP2P)
  125. {
  126. return [self checkP2PReceipts:receipts];
  127. }
  128. else
  129. {
  130. return [self checkTeamReceipts:receipts];
  131. }
  132. }
  133. - (NSDictionary *)checkP2PReceipts:(NSArray<NIMMessageReceipt *> *)receipts
  134. {
  135. BOOL hasConfig = self.sessionConfig && [self.sessionConfig respondsToSelector:@selector(shouldHandleReceiptForMessage:)];
  136. NSMutableDictionary *dict = [NSMutableDictionary dictionary];
  137. // BOOL findLastReceipt = NO;
  138. for (NSInteger i = [[self.dataSource items] count] - 1; i >= 0; i--) {
  139. id item = [[self.dataSource items] objectAtIndex:i];
  140. if ([item isKindOfClass:[NIMMessageModel class]]) {
  141. NIMMessageModel *model = (NIMMessageModel *)item;
  142. NIMMessage *message = [model message];
  143. if (message.isOutgoingMsg) {
  144. if (message.isRemoteRead && hasConfig && [self.sessionConfig shouldHandleReceiptForMessage:message])
  145. {
  146. if (model.shouldShowReadLabel) {
  147. }else{
  148. dict[@(i)] = model;
  149. model.shouldShowReadLabel = YES;
  150. }
  151. }
  152. }
  153. }
  154. }
  155. return dict;
  156. }
  157. - (NSDictionary *)checkTeamReceipts:(NSArray<NIMMessageReceipt *> *)receipts
  158. {
  159. NSMutableSet *filtedMessaegeIds = nil;
  160. if (receipts.count)
  161. {
  162. //说明只要局部更新
  163. filtedMessaegeIds = [[NSMutableSet alloc] init];
  164. for (NIMMessageReceipt *receipt in receipts)
  165. {
  166. [filtedMessaegeIds addObject:receipt.messageId];
  167. }
  168. }
  169. NSMutableDictionary *dict = [NSMutableDictionary dictionary];
  170. BOOL hasConfig = self.sessionConfig && [self.sessionConfig respondsToSelector:@selector(shouldHandleReceiptForMessage:)];
  171. NSMutableArray *queryMessages = [NSMutableArray array];
  172. for (NSInteger i = [[self.dataSource items] count] - 1; i >= 0; i--)
  173. {
  174. id item = [[self.dataSource items] objectAtIndex:i];
  175. if ([item isKindOfClass:[NIMMessageModel class]])
  176. {
  177. NIMMessageModel *model = (NIMMessageModel *)item;
  178. NIMMessage *message = [model message];
  179. if (filtedMessaegeIds && ![filtedMessaegeIds containsObject:message.messageId])
  180. {
  181. //本次刷新不包含此消息,略过
  182. continue;
  183. }
  184. if (!receipts)
  185. {
  186. //说明是全部刷新,这个时候消息的回执数可能是过期的,查刷一下
  187. [queryMessages addObject:message];
  188. }
  189. if (message.isOutgoingMsg)
  190. {
  191. if (message.setting.teamReceiptEnabled &&
  192. hasConfig &&
  193. [self.sessionConfig shouldHandleReceiptForMessage:message])
  194. {
  195. model.shouldShowReadLabel = YES;
  196. dict[@(i)] = model;
  197. }
  198. }
  199. }
  200. }
  201. if ([queryMessages count])
  202. {
  203. [[NIMSDK sharedSDK].chatManager refreshTeamMessageReceipts:queryMessages];
  204. }
  205. return dict;
  206. }
  207. - (void)sendMessageReceipt:(NSArray *)messages
  208. {
  209. //只有在当前 Application 是激活的状态下才发送已读回执
  210. if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)
  211. {
  212. if (self.session.sessionType == NIMSessionTypeP2P)
  213. {
  214. [self sendP2PMessageReceipt:messages];
  215. }
  216. if (self.session.sessionType == NIMSessionTypeTeam)
  217. {
  218. [self sendTeamMessageReceipt:messages];
  219. }
  220. }
  221. }
  222. - (void)sendP2PMessageReceipt:(NSArray *)messages
  223. {
  224. //找到最后一个需要发送已读回执的消息标记为已读
  225. for (NSInteger i = [messages count] - 1; i >= 0; i--) {
  226. id item = [messages objectAtIndex:i];
  227. NIMMessage *message = nil;
  228. if ([item isKindOfClass:[NIMMessage class]])
  229. {
  230. message = item;
  231. }
  232. else if ([item isKindOfClass:[NIMMessageModel class]])
  233. {
  234. message = [(NIMMessageModel *)item message];
  235. }
  236. if (message)
  237. {
  238. if (!message.isOutgoingMsg &&
  239. self.sessionConfig &&
  240. [self.sessionConfig respondsToSelector:@selector(shouldHandleReceiptForMessage:)] &&
  241. [self.sessionConfig shouldHandleReceiptForMessage:message])
  242. {
  243. NIMMessageReceipt *receipt = [[NIMMessageReceipt alloc] initWithMessage:message];
  244. [[[NIMSDK sharedSDK] chatManager] sendMessageReceipt:receipt
  245. completion:nil]; //忽略错误,如果失败下次再发即可
  246. return;
  247. }
  248. }
  249. }
  250. }
  251. - (void)sendTeamMessageReceipt:(NSArray *)messages
  252. {
  253. NSMutableArray *receipts = [NSMutableArray array];
  254. for (NIMMessage *item in messages)
  255. {
  256. NIMMessage *message = nil;
  257. if ([item isKindOfClass:[NIMMessage class]])
  258. {
  259. message = item;
  260. }
  261. else if ([item isKindOfClass:[NIMMessageModel class]])
  262. {
  263. message = [(NIMMessageModel *)item message];
  264. }
  265. if (message)
  266. {
  267. if (!message.isOutgoingMsg && message.setting.teamReceiptEnabled)
  268. {
  269. NIMMessageReceipt *receipt = [[NIMMessageReceipt alloc] initWithMessage:message];
  270. [receipts addObject:receipt];
  271. }
  272. }
  273. }
  274. if([receipts count])
  275. {
  276. [[[NIMSDK sharedSDK] chatManager] sendTeamMessageReceipts:receipts
  277. completion:nil];
  278. }
  279. }
  280. @end
  281. @implementation NIMSessionMessageOperateResult
  282. @end