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.m  添加接收透传消息的方法,

 接收透传消息是环信系统自带的方法。我这边还有一个没做,就是别人撤回后在当前聊天界面的刷新没做好,你们自己做一下。

是不是有点坑 ,我也觉得,但是最起码能给你们一些方向,就将就的看下去吧 ,嘟嘟嘟嘟。。

你们要有好方法告诉我~

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 // 删除消息

  - (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;
  }

 

感觉我做的很粗糙,但是希望能帮到你们~  

   

 

 

转载于:https://www.cnblogs.com/chenzq12/p/6295475.html

### 下载 Popper.min.js 文件的方法 对于希望获取 `popper.min.js` 的开发者来说,可以通过多种方式来实现这一目标。通常情况下,推荐通过官方渠道或可靠的分发网络 (CDN) 来获得最新的稳定版文件。 #### 使用 CDN 获取 Popper.min.js 最简单的方式之一是从流行的 CDN 中加载所需的 JavaScript 库。这不仅简化了集成过程,还可能提高性能,因为许多用户已经缓存了来自这些服务提供商的内容。例如: ```html <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2/dist/umd/popper.min.js"></script> ``` 这种方式不需要手动下载文件到本地服务器;只需将上述 `<script>` 标签添加至 HTML 文档中的适当位置即可立即使用 Popper 功能[^1]。 #### 从 npm 或 yarn 安装 如果项目采用模块化构建工具链,则可以直接利用包管理器如 npm 或 Yarn 进行安装。命令如下所示: ```bash npm install @popperjs/core # 或者 yarn add @popperjs/core ``` 之后可以根据具体需求引入特定功能模块,而不是整个库,从而减少打包后的体积并优化加载速度[^2]。 #### 访问 GitHub 发布页面下载压缩包 另一种方法是访问 Popper.js 的 [GitHub Releases](https://github.com/popperjs/popper-core/releases) 页面,在这里可以选择不同版本的 tarball 或 zip 归档进行下载解压操作。这种方法适合那些偏好离线工作环境或是想要定制编译选项的人群[^3]。 #### 手动克隆仓库 最后一种较为少见但也可行的办法便是直接克隆完整的 Git 存储库副本。这样可以获得开发分支以及历史记录等更多信息,适用于贡献代码或者深入学习内部机制的情况。 ```bash git clone https://github.com/popperjs/popper-core.git cd popper-core ``` 完成以上任一途径后便能成功取得所需版本的 Popper.min.js 文件,并将其应用于个人项目之中[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值