iOS 环信消息撤回
这两天在做环信的消息回撤,在网上找了许久没有这种案例,之后官方的一些方法,但是自己做,还是需要花点时间去整理,所以我决定等我把这个做好之后,分享给大家,如果做的不好多多指教,谢谢~
首先要实现消息撤回就是两个步骤,一个是发送要回撤的透传消息 。一个是接收透传信息,删除要回撤的消息。
第一步 : ChatViewController.m 自己定义一个
UIMenuItem *_messageRetracementMenuItem;
第二步
这个方法里面添加一下撤回字段,我把整段都复制过来了,你们对一下
- (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];
}
第三步:实现这个回撤的方法 ,我这边做的是在两分钟内撤回,超过两分钟提示
- (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:@"消息已经超过两分钟 无法撤回"];
}
}
}
// 你撤回之后会发现你消息撤回了,但是还在,但是你要重新运行一下撤回的消息就会没有,所以就是有一步当你撤回的时候,还要手动删除一下。
主要删除 self.conversation,self.dataArray,self.messsagesSource,这三个,然后刷新一下。
其中 REVOKE_FLAG 和 msgId 一定要和安卓对应,两边要写一样的,要不然另一方撤回这边是接收不到的或者你这边撤回另一方收不到。
还有 message.chatType 也要注意,如果你做的不只单聊,那就要判断一下,我上面代码有些,一个群聊,一个单聊。
// 发送回撤的透传消息
- (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.h 添加接收透传消息的方法,
接收透传消息是环信系统自带的方法。我这边还有一个没做好,就是别人撤回后在当前聊天界面的刷新没刷新好,你们自己做一下。
1 // 接收透传消息
2 - (void)didReceiveCmdMessages:(NSArray *)aCmdMessages {
3 BOOL isRefreshCons = YES;
4 for (EMMessage *cmdMessage in aCmdMessages) {
5 EMCmdMessageBody *body = (EMCmdMessageBody *)cmdMessage.body;
6 if ([body.action isEqualToString:@"REVOKE_FLAG"]) {
7 NSString *revokeMessageId = cmdMessage.ext[@"msgId"];
8 BOOL isSuccess = [self removeRevokeMessageWithChatter:cmdMessage.conversationId conversationType:(EMConversationType)cmdMessage.chatType messageId:revokeMessageId];
9 if (isSuccess) {
10 if (_chatVC == nil) {
11 _chatVC = [self _getCurrentChatView];
12 }
13 BOOL isChatting = NO;
14 if (_chatVC) {
15 isChatting = [cmdMessage.conversationId isEqualToString:_chatVC.conversation.conversationId];
16 }
17 if (_chatVC == nil || !isChatting) {
18 [self _handleReceivedAtMessage:cmdMessage];
19 if (self.conversationListVC) {
20 [[NSNotificationCenter defaultCenter] postNotificationName:@"conversationListRefresh" object:nil];
21 }
22 if (self.mainVC) {
23 [[NSNotificationCenter defaultCenter] postNotificationName:@"conversationListRefresh" object:nil];
24 [self.mainVC setupUnreadMessageCount];
25 }
26 return;
27 }
28 if (isChatting) {
29 isRefreshCons = NO;
30 }
31 if (isRefreshCons) {
32 if (self.conversationListVC) {
33 [[NSNotificationCenter defaultCenter] postNotificationName:@"conversationListRefresh" object:nil];
34 }
35 if (self.contactViewVC) {
36 [[NSNotificationCenter defaultCenter] postNotificationName:@"setupUnreadMessageCount" object:nil];
37 }
38 }
39 } else {
40 NSLog(@"接收失败");
41 }
42 }
43 }
44 }
1 // 删除消息
2 - (BOOL)removeRevokeMessageWithChatter:(NSString *)aChatter
3 conversationType:(EMConversationType)type
4 messageId:(NSString *)messageId{
5
6 EMConversation *conversation = [[EMClient sharedClient].chatManager getConversation:aChatter type:type createIfNotExist:YES];
7 [conversation deleteMessageWithId:messageId];
8 return YES;
9 }
这样就好了,希望能帮到你们~
iOS 环信消息撤回的更多相关文章
- iOS 环信透传cmd消息多次重复接收,解决办法
由于项目需求,需要在项目中接到消息的时候做不同界面的不同的操作,哪儿需要哪儿就要添加代理:引起代理事件重复执行:所以要在VC显示的时候添加代理,消失的时候删除代理 环信 透传 消息多次接收情况(由于代 ...
- 集成IOS 环信SDK
集成IOS SDK 在您阅读此文档时,我们假定您已经具备了基础的 iOS 应用开发经验,并能够理解相关基础概念. 下载SDK 通过Cocoapods下载地址 不包含实时语音版本SDK(EaseMobC ...
- iOS 环信集成项目应用
环信iOS端3.0版本集成记录--聊天界面篇 环信离线推送证书... 1,环信处在后台的时候,消息的接收与推送 离线发推送 配置属性 EMCallOptions *options = [[EMClie ...
- iOS: 环信的推送
原文:http://m.blog.csdn.net/article/details?id=38824551 1.先创建一个apns证书,链接如下 http://developer.easemob.co ...
- iOS 环信集成问题(连文档都不说明的坑。。)
首先,关于环信SDK的下载和一些依赖库的添加,在此我就不做详细介绍,(http://www.easemob.com/download/im)附上环信官网文档,可以看一下,上面都可以下载,也有相关配置介 ...
- iOS 环信集成单聊界面,出现消息重复问题
解决办法很简单,数据重复就是EaseMessageViewController和ChatViewController重复调用了这个吧?//通过会话管理者获取收发消息 [self tableViewDi ...
- [Java]直播方案----[接入环信聊天室]+[腾讯云直播]
辛辛苦苦写的,转载请注明一下,这点信任我想还是有的吧,谢谢了. http://www.cnblogs.com/applerosa/p/7162268.html 之前做了直播,一直没时间写,好不容易闲下 ...
- 李洪强iOS开发之-环信04_消息
李洪强iOS开发之-环信04_消息 消息:IM 交互实体,在 SDK 中对应的类型是 EMMessage.EMMessage 由 EMMessageBody 组成. 构造消息 构造文字消息 EMT ...
- 李洪强iOS开发之-环信05_EaseUI 使用指南
李洪强iOS开发之-环信05_EaseUI 使用指南 EaseUI 使用指南 简介 EaseUI 封装了 IM 功能常用的控件(如聊天会话.会话列表.联系人列表).旨在帮助开发者快速集成环信 SDK. ...
随机推荐
- line-box(转)
inline-block是什么? Inline-block是元素display属性的一个值.这个名字的由来是因为,display设置这个值的元素,兼具行内元素( inline elements)跟块级 ...
- 利用dokan作虚拟磁盘开发
dokan是用户态的文件系统驱动,可以称之为fuse for windows.可以用来开发虚拟磁盘,即在“我的电脑”中虚拟出一个硬盘来,可以是硬盘,也可以是可移动磁盘或者网络硬盘. CreateFil ...
- w3school之JavaScript学习笔记
在前端测试过程中,少不了听到开发说到JS,JS在webJavaScript 是浏览器脚本语言(简称JS),主要用来向HTML页面添加交互行为. 学习网址:http://www.w3school.com ...
- mysql建表---级联删除
CREATE TABLE `roottb` ( `id` INT(11) UNSIGNED AUTO_INCREMENT NOT NULL, `data` VARCHAR(100) NOT NUL ...
- express4.x中路由中间件和挂载路径的关系
express4.x 中一个路由中间件可以挂载到多个路由上,一个路由也可以绑定多个路由中间件,如: //多个路由匹配一个路由中间件 app.use(['/gre+t', '/hel{2}o'], gr ...
- [iOS Animation]-CALayer 绘图效率
绘图 不必要的效率考虑往往是性能问题的万恶之源. ——William Allan Wulf 在第12章『速度的曲率』我们学习如何用Instruments来诊断Core Animation性能问题.在构 ...
- isKindOfClass,isMemberOfClass使用备忘
isMemberOfClass 判断是否是属于这类的实例isKindOfClass 判断是否是这个类或者这个类的子类的实例 if ([teacher isKindOfClass:[Teacher cl ...
- POJ3268Dijkstra
题意:给定n个点,m条边,求所有顶点中到顶点x的来回最短距离 分析:考虑到数据范围,选用Dijkstra,用Floyd会超时 #include <iostream> #include &l ...
- iOS动画特效 分类: ios技术 2015-05-15 16:29 311人阅读 评论(0) 收藏
关于图层的几个坐标系. 对于ios来说,坐标系的(0,0)点在左上角,就是越往下,Y值越大.越往右,X值越大. 一个图层的frame,它是position,bounds,anchorPoint和tra ...
- jquery遍历二维数组
function eachTowArray() { var ar = [[1,2,3],[4,5,6],[7,8,9]]; var result=""; //结果存放变量 ...