这两天在做环信的消息回撤,在网上找了许久没有这种案例,之后官方的一些方法,但是自己做,还是需要花点时间去整理,所以我决定等我把这个做好之后,分享给大家,如果做的不好多多指教,谢谢~
首先要实现消息撤回就是两个步骤,一个是发送要回撤的透传消息 。一个是接收透传信息,删除要回撤的消息。
第一步 : ChatViewController.m 自己定义一个
|
1
|
UIMenuItem *_messageRetracementMenuItem; |
第二步
这个方法里面添加一下撤回字段,我把整段都复制过来了,你们对一下
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
- (void)showMenuViewController:(UIView *)showInView andIndexPath:(NSIndexPath *)indexPath messageType:(EMMessageBodyType)messageType { if (self.menuController == nil) { self.menuController = [UIMenuController sharedMenuController]; } if (_deleteMenuItem == nil) { _deleteMenuItem = [[UIMenuItem alloc] initWithTitle:@"删除" action:@selector(deleteMenuAction:)]; } if (_copyMenuItem == nil) { _copyMenuItem = [[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(copyMenuAction:)]; } if (_transpondMenuItem == nil) { _transpondMenuItem = [[UIMenuItem alloc] initWithTitle:@"转发" action:@selector(transpondMenuAction:)]; } if (_messageRetracementMenuItem == nil) { _messageRetracementMenuItem = [[UIMenuItem alloc] initWithTitle:@"撤回" action:@selector(messageRetracementMenuAction:)]; } NSString *loginUsername = [[EMClient sharedClient] currentUsername]; id<imessagemodel> model = [self.dataArray objectAtIndex:self.menuIndexPath.row]; if (messageType == EMMessageBodyTypeText) { if ([loginUsername isEqualToString:model.message.from]) { [self.menuController setMenuItems:@[_copyMenuItem, _deleteMenuItem,_transpondMenuItem,_messageRetracementMenuItem]]; } else { [self.menuController setMenuItems:@[_copyMenuItem, _deleteMenuItem,_transpondMenuItem]]; } } else if (messageType == EMMessageBodyTypeImage){ if ([loginUsername isEqualToString:model.message.from]) { [self.menuController setMenuItems:@[_deleteMenuItem,_transpondMenuItem,_messageRetracementMenuItem]]; } else { [self.menuController setMenuItems:@[_deleteMenuItem,_transpondMenuItem]]; } } else { if ([loginUsername isEqualToString:model.message.from]) { [self.menuController setMenuItems:@[_deleteMenuItem,_messageRetracementMenuItem]]; } else { [self.menuController setMenuItems:@[_deleteMenuItem]]; } } [self.menuController setTargetRect:showInView.frame inView:showInView.superview]; [self.menuController setMenuVisible:YES animated:YES]; } </imessagemodel> |
第三步:实现这个回撤的方法 ,我这边做的是在两分钟内撤回,超过两分钟提示
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
- (void)messageRetracementMenuAction:(id)sender { if (self.menuIndexPath && self.menuIndexPath.row > 0) { id<imessagemodel> model = [self.dataArray objectAtIndex:self.menuIndexPath.row]; NSString *messageId = model.message.messageId; // 发送这条消息在服务器的时间戳 NSTimeInterval time1 = (model.message.serverTime) / 1000.0; // 当前的时间戳 NSTimeInterval nowTime = [[NSDate date] timeIntervalSince1970]; NSTimeInterval cha = nowTime - time1; NSInteger timecha = cha; if (timecha <= 120) { // 开始调用发送消息回撤的方法 [self revokeMessageWithMessageId:messageId conversationId:self.conversation.conversationId]; } else { [self showHint:@"消息已经超过两分钟 无法撤回"]; } } }</imessagemodel> |
// 你撤回之后会发现你消息撤回了,但是还在,但是你要重新运行一下撤回的消息就会没有,所以就是有一步当你撤回的时候,还要手动删除一下。
主要删除 self.conversation,self.dataArray,self.messsagesSource,这三个,然后刷新一下。
其中 REVOKE_FLAG 和 msgId 一定要和安卓对应,两边要写一样的,要不然另一方撤回这边是接收不到的或者你这边撤回另一方收不到。
还有 message.chatType 也要注意,如果你做的不只单聊,那就要判断一下,我下面代码有些,一个群聊,一个单聊。
// 发送回撤的透传消息
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
- (void)revokeMessageWithMessageId:(NSString *)aMessageId conversationId:(NSString *)conversationId { EMCmdMessageBody *body = [[EMCmdMessageBody alloc] initWithAction:@"REVOKE_FLAG"]; NSDictionary *ext = @{@"msgId":aMessageId}; NSString *currentUsername = [EMClient sharedClient].currentUsername; EMMessage *message = [[EMMessage alloc] initWithConversationID:conversationId from:currentUsername to:conversationId body:body ext:ext]; if (self.conversation.type == EMConversationTypeGroupChat){ message.chatType = EMChatTypeGroupChat; } else { message.chatType = EMChatTypeChat; } //发送cmd消息 [[EMClient sharedClient].chatManager asyncSendMessage:message progress:nil completion:^(EMMessage *message, EMError *error) { if (!error) { NSLog(@"发送成功"); // 需要自己从dataArray里将聊天消息删掉, 还有self.conversation里,最后刷新 NSMutableIndexSet *indexs = [NSMutableIndexSet indexSetWithIndex:self.menuIndexPath.row]; NSMutableArray *indexPaths = [NSMutableArray arrayWithObjects:self.menuIndexPath, nil]; [self.conversation deleteMessageWithId:aMessageId]; [self.messsagesSource removeObject:message]; if (self.menuIndexPath.row - 1 >= 0) { id nextMessage = nil; id prevMessage = [self.dataArray objectAtIndex:(self.menuIndexPath.row - 1)]; if (self.menuIndexPath.row + 1 < [self.dataArray count]) { nextMessage = [self.dataArray objectAtIndex:(self.menuIndexPath.row + 1)]; } if ((!nextMessage || [nextMessage isKindOfClass:[NSString class]]) && [prevMessage isKindOfClass:[NSString class]]) { [indexs addIndex:self.menuIndexPath.row - 1]; [indexPaths addObject:[NSIndexPath indexPathForRow:(self.menuIndexPath.row - 1) inSection:0]]; } } [self.dataArray removeObjectsAtIndexes:indexs]; [self.tableView beginUpdates]; [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade]; [self.tableView endUpdates]; if ([self.dataArray count] == 0) { self.messageTimeIntervalTag = -1; } } else { NSLog(@"发送失败"); } }]; } |
第四步:在你接收消息 - (void)didReceiveMessages:(NSArray *)aMessages 这个方法的控制器里 ChatDemoHelper.m 添加接收透传消息的方法,
接收透传消息是环信系统自带的方法。我这边还有一个没做好,就是别人撤回后在当前聊天界面的刷新没刷新好,你们自己做一下。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
1 // 接收透传消息 - (void)didReceiveCmdMessages:(NSArray *)aCmdMessages { BOOL isRefreshCons = YES; for (EMMessage *cmdMessage in aCmdMessages) { EMCmdMessageBody *body = (EMCmdMessageBody *)cmdMessage.body; if ([body.action isEqualToString:@"REVOKE_FLAG"]) { NSString *revokeMessageId = cmdMessage.ext[@"msgId"]; BOOL isSuccess = [self removeRevokeMessageWithChatter:cmdMessage.conversationId conversationType:(EMConversationType)cmdMessage.chatType messageId:revokeMessageId]; if (isSuccess) { if (_chatVC == nil) { _chatVC = [self _getCurrentChatView]; } BOOL isChatting = NO; if (_chatVC) { isChatting = [cmdMessage.conversationId isEqualToString:_chatVC.conversation.conversationId]; } if (_chatVC == nil || !isChatting) { [self _handleReceivedAtMessage:cmdMessage]; if (self.conversationListVC) { [[NSNotificationCenter defaultCenter] postNotificationName:@"conversationListRefresh" object:nil]; } if (self.mainVC) { [[NSNotificationCenter defaultCenter] postNotificationName:@"conversationListRefresh" object:nil]; [self.mainVC setupUnreadMessageCount]; } return; } if (isChatting) { isRefreshCons = NO; } if (isRefreshCons) { if (self.conversationListVC) { [[NSNotificationCenter defaultCenter] postNotificationName:@"conversationListRefresh" object:nil]; } if (self.contactViewVC) { [[NSNotificationCenter defaultCenter] postNotificationName:@"setupUnreadMessageCount" object:nil]; } } } else { NSLog(@"接收失败"); } } } } |
1 // 删除消息
|
1
2
3
4
5
6
7
8
|
- (BOOL)removeRevokeMessageWithChatter:(NSString *)aChatter conversationType:(EMConversationType)type messageId:(NSString *)messageId{ EMConversation *conversation = [[EMClient sharedClient].chatManager getConversation:aChatter type:type createIfNotExist:YES]; [conversation deleteMessageWithId:messageId]; return YES;} |
这样就好了,希望能帮到你们~
浙公网安备 33010602011771号