这两天在做环信的消息回撤,在网上找了许久没有这种案例,之后官方的一些方法,但是自己做,还是需要花点时间去整理,所以我决定等我把这个做好之后,分享给大家,如果做的不好多多指教,谢谢~
首先要实现消息撤回就是两个步骤,一个是发送要回撤的透传消息 。一个是接收透传信息,删除要回撤的消息。
第一步 : 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;} |
这样就好了,希望能帮到你们~
本文介绍了在iOS上实现环信消息撤回的详细步骤,包括发送撤回通知、接收并删除消息。重点在于理解撤回机制,如设置撤回时间限制、同步删除本地消息记录,并确保与安卓端的兼容。代码示例涵盖了关键操作,有助于开发者快速实现该功能。

753

被折叠的 条评论
为什么被折叠?



