环信iOS消息撤回

来源:互联网 发布:mac svg 制作工具知乎 编辑:程序博客网 时间:2024/04/30 01:47

最近在做输入状态改变, 消息撤回 , 置顶聊天 , 位置共享功能, 今天把做的消息回撤的功能整理下给大家分享, 如有做的不对的地方或者更好的地方, 希望大家多多指教

A用户发消息给B用户,当需要回撤的时候,将要回撤消息的id通过扩展消息发送给B,B检测到回撤的透传消息后,将对应 messageid 的消息从数据库删除。

  1. A用户发送消息。
  2. A用户需要撤回某条消息,将消息id通过扩展消息发送到用户B。
  3. B用户收到扩展消息,解析其中的messageid,从数据库删除对应消息。

第一步: 添加消息撤回菜单 在ChatViewController中添加

    UIMenuItem *_retracementMenuItem;
然后在中添加菜单
- (void)showMenuViewController:(UIView *)showInView                     andIndexPath:(NSIndexPath *)indexPath                      messageType:(EMMessageBodyType)messageType
代码如下: (注意这里我写了阅后即焚功能, 不能的话该部分可以去掉, 另外我这边的需求是聊天室消息不能撤回)

    //撤回    if (_retracementMenuItem == nil) {        _retracementMenuItem= [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"retracement", @"Retracement")                                                        action:@selector(messageRetracementMenuAction:)];    }        id<IMessageModel> model = [self.dataArray objectAtIndex:self.menuIndexPath.row];    BOOL isFireMsg = [[model.message.ext objectForKey:kGoneAfterReadKey] boolValue];    NSMutableArray *items = [NSMutableArray array];    if (!isFireMsg) {        switch (messageType) {            case EMMessageBodyTypeText:            {                [items addObject:_copyMenuItem];            }            case EMMessageBodyTypeImage:            case EMMessageBodyTypeVideo:            {                [items addObject:_transpondMenuItem];            }            case EMMessageBodyTypeVoice:            case EMMessageBodyTypeFile:            case EMMessageBodyTypeLocation:            {                     }                break;            default:                break;        }    }        [items addObject:_deleteMenuItem];        NSString *currentUsername = [EMClient sharedClient].currentUsername;    NSString *from = model.message.from;    if ([currentUsername isEqualToString:from]&&self.conversation.type != EMChatTypeChatRoom) {        [items addObject:retracementMenuItem];    }        [self.menuController setMenuItems:items];    [self.menuController setTargetRect:showInView.frame inView:showInView.superview];    [self.menuController setMenuVisible:YES animated:YES];}

第二步 : 实现撤回方法





第三步 : 在你 ChatDemoHelper.m  添加接收透传消息的方法

删除消息 :


添加撤回的消息提示:


接收撤回的cmd消息要做的事:(这里代码太多,我就直接贴代码了)

// 接收撤回透传消息- (void)tCmdRevokeMessagesDidReceive:(NSArray *)aCmdMessages {    BOOL isRefreshCons = YES;    NSMutableArray *revokeAry = [[NSMutableArray alloc] init];    NSMutableArray *msgAry = [[NSMutableArray alloc] init];    BOOL isRevoke = NO;    for (EMMessage *cmdMessage in aCmdMessages) {        EMCmdMessageBody *body = (EMCmdMessageBody *)cmdMessage.body;        isRevoke = [body.action isEqualToString:REVOKE_FLAG];        if (isRevoke) {            [revokeAry addObject:cmdMessage];        }        else{            [msgAry addObject:cmdMessage];        }    }        if (isRevoke) {        for (EMMessage *cmdRevokeMessage in revokeAry) {            //删除撤回的消息            EMConversation *conversation = [[EMClient sharedClient].chatManager getConversation:cmdRevokeMessage.conversationId                                                                                           type:(EMConversationType)cmdRevokeMessage.chatType                                                                               createIfNotExist:YES];            NSString *revokeMessageId = cmdRevokeMessage.ext[MSG_ID];            EMMessage *newMessage = [self buildInsertMessageWithConversation:conversation                                                                  CmdMessage:cmdRevokeMessage                                                                   messageId:revokeMessageId];            //判断是否删除成功            BOOL isSuccess = [self removeRevokeMessageWithConversation:conversation                                                             messageId:revokeMessageId];            if (isSuccess)  { //更新UI,插入一条撤回消息                [conversation insertMessage:newMessage error:nil];                if (self.chatVC == nil) {                    self.chatVC = [self _getCurrentChatView];//todo                }                BOOL isChatting = NO;                if (self.chatVC)  {                    isChatting = [cmdRevokeMessage.conversationId isEqualToString:self.chatVC.conversation.conversationId];                    NSInteger index = - 1;                    for (int i = 0; i < self.chatVC.messsagesSource.count; i++) {                        EMMessage *msg = self.chatVC.messsagesSource[i];                        if ([msg.messageId isEqualToString:revokeMessageId]) {                            index = i;                            break;                        }                    }                    if (index > -1) {                        [self.chatVC.messsagesSource replaceObjectAtIndex:index withObject:newMessage];                    }                                                            dispatch_async(dispatch_get_main_queue(), ^{                        self.chatVC.messageTimeIntervalTag = 0;                        NSArray *formattedMessages = (NSArray *)[self.chatVC performSelector:@selector(formatMessages:)                                                                                  withObject:self.chatVC.messsagesSource];                        [self.chatVC.dataArray removeAllObjects];                        [self.chatVC.dataArray addObjectsFromArray:formattedMessages];                        [self.chatVC.tableView reloadData];                        [[EMClient sharedClient].chatManager updateMessage:newMessage completion:nil];                    });                }                else if (self.chatVC == nil || !isChatting) {                    if (self.conversationListVC) {                                                [[NSNotificationCenter defaultCenter] postNotificationName:@"conversationListRefresh" object:nil];                        [self.conversationListVC refresh];                    }                    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];                        [self.conversationListVC refresh];                    }                    if (self.contactViewVC) {                        [[NSNotificationCenter defaultCenter] postNotificationName:@"setupUnreadMessageCount" object:nil];                        [self.mainVC setupUnreadMessageCount];                    }                }            }  else {                NSLog(@"接收失败");            }        }    }}


好了, 那么撤回部分我们就大致做完了, 你还需要做的就是改下撤回消息的显示在EaseMessageViewController中, 添加并判断是否是撤回消息的cell

今天收到反馈说撤回消息已经实现,但是界面不行,如何在正中间显示 XX 已撤回消息,现在的显示位置是发送者或者接受者的位置,我想让它在中间显示

解决方法 :

1. 想可以在插入的提示消息中设置ext添加自定义字段,用于验证此消息代表撤销提示的功能。然后根据这个字段去加载自定义的cell或者EaseUI的TimeCell。(2.x版本的demoUI上实现了,可以作参考)。

2.在继承自EaseMessageViewController的子类中实现
- (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id)model
在此回调方法中,通过判断model.message.ext中是否存在1步骤中设置的字段,且其值不为空或者其值为YES,
初始化一个EaseMessageTimeCell,为cell.title赋值为[(EMTextMessageBody *)model.message.body text]
返回此创建的cell。如果model.message.ext不存在1步骤的字段,返回nil

0 0
原创粉丝点击