iOS 环信 EaseUI 的优化

背景

去年曾为了项目的一个即时通信功能集成过环信,因为考虑开发的低成本,就直接使用了环信的 EaseUI

环信的文档提供了很多好友管理、群聊操作的API,但当你看到下图后,这些api直接可以无视掉

iOS 环信 EaseUI 的优化_第1张图片


所以环信当作工具来使用即可,千万别用他的后台系统(我的公司安卓那边莫名的相信环信后台,白白浪费了近两个多星期)


为什么需要优化?

因为环信的EaseUI,是根据环信自己后台开发的,所以需要让EaseUI更好地跟我们自己的后台关联起来

iOS 环信 EaseUI 的优化_第2张图片

红色圈出来的就是我接下来所做的优化的内容

ps:一开始我以为,在拉取好友列表的时候判断好,就基本没有大碍!但是后面经测试,在聊天的过程中,如果对方把你删除,聊天依旧可以继续,所以就需要对 EaseUI 的源码开刀。


具体流程

EaseUI 使用起来十分便捷,只需要自己创建一个继承于 EaseMessageViewController 的控制器即可

接着实现 EaseMessageViewControllerDataSource 该协议的

- (id)messageViewController:(EaseMessageViewController *)viewController
                           modelForMessage:(EMMessage *)message;

便可以对聊天内容的环信用户设置自定义头像和名字



接来下便开始修改他的源码:

第一步

打开 EaseUI 里面的 EaseMessageViewController.h 文件

在 EaseMessageViewControllerDelegate 下添加以下代码

/**
 * 是否需要发送这条消息  return false 将会阻止该消息的发送  - pfboy add
 *
 * @param viewController _
 * @param message 自己发送出去的消息
 * @param block 对发出去的数据的,进行校验,通过block的参数isDataRight返回数据的正确性
 *
 */
- (void) messageViewController:(EaseMessageViewController *)viewController willSendMessage:(EMMessage *)message  resultBlock:(void(^)(BOOL isDataRight)) block;

/**
 * 是否需要发送这条消息  return false 将会阻止该消息的发送  - pfboy add
 *
 * @param viewController _
 * @param message 接收到的数据
 * @param block 对接收到的数据,进行校验,通过block的参数isDataRight返回数据的正确性
 *
 */
- (void) messageViewController:(EaseMessageViewController *)viewController willReceiveMessage:(EMMessage *)message  resultBlock:(void(^)(BOOL isDataRight)) block;

这个是为了最后,我们可以在自己的 Controller 通过这两个方法,来判断发收信息的是否来自好友或者群聊

因为需要通过http请求来判断好友的真实性,所以使用block 进行控制

第二步

接着打开文件 EaseMessageViewController.m  并滑动到1721行

将原 _sendMessage 函数

- (void)_sendMessage:(EMMessage *)message
{
    if (self.conversation.type == EMConversationTypeGroupChat){
        message.chatType = EMChatTypeGroupChat;
    }
    else if (self.conversation.type == EMConversationTypeChatRoom){
        message.chatType = EMChatTypeChatRoom;
    }
    
    [self addMessageToDataSource:message
                        progress:nil];
    
    __weak typeof(self) weakself = self;
    [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {
        if (!aError) {
            [weakself _refreshAfterSentMessage:aMessage];
        }
        else {
            [weakself.tableView reloadData];
        }
    }];
}

改成以下代码

/判断该消息是否需要截断  pfboy add
- (void) _sendCorrectMessage:(EMMessage *)message{
    __weak typeof(self) weakself = self;
    [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {
        if (!aError) {
            [weakself _refreshAfterSentMessage:aMessage];
        }
        else {
            [weakself.tableView reloadData];
        }
    }];
}

// hook 这个地址
- (void) _sendMessage:(EMMessage *)message
{
    if (self.conversation.type == EMConversationTypeGroupChat){
        message.chatType = EMChatTypeGroupChat;
    }
    else if (self.conversation.type == EMConversationTypeChatRoom){
        message.chatType = EMChatTypeChatRoom;
    }
    
    [self addMessageToDataSource:message
                        progress:nil];
    
    //判断该消息是否需要截断  pfboy add
    if ([self.delegate respondsToSelector:@selector(messageViewController:willSendMessage:resultBlock:)]) {
        __weak typeof(self) weakself = self;
        [self.delegate messageViewController:self willSendMessage:message resultBlock:^(BOOL isDataRight) {
            if (isDataRight) {
                [weakself _sendCorrectMessage:message];
            }
        }];
    } else {
        // 如果没有实现该代理,则不会更改源码的流程
        [self _sendCorrectMessage:message];
    }
    
}
第三步

EaseMessageViewController.h 滑动到 1137 行将方法 statusButtonSelcted 替换成以下代码

- (void) _resendMessage:(id)model{
    __weak typeof(self) weakself = self;
    [[[EMClient sharedClient] chatManager] resendMessage:model.message progress:nil completion:^(EMMessage *message, EMError *error) {
        if (!error) {
            [weakself _refreshAfterSentMessage:message];
        }
        else {
            [weakself.tableView reloadData];
        }
    }];
    
    [self.tableView reloadData];
}

// hook 重发地址
- (void)statusButtonSelcted:(id)model withMessageCell:(EaseMessageCell*)messageCell
{
    if ((model.messageStatus != EMMessageStatusFailed) && (model.messageStatus != EMMessageStatusPending))
    {
        return;
    }
    //判断该消息是否需要截断  pfboy add
    if ([self.delegate respondsToSelector:@selector(messageViewController:willSendMessage:resultBlock:)]) {
        __weak typeof(self) weakself = self;
        [self.delegate messageViewController:self willSendMessage:model.message resultBlock:^(BOOL isDataRight) {
            if (isDataRight) {
                [weakself _resendMessage:model];
            }
        }];
    } else {
        // 如果没有实现该代理,则不会更改源码的流程
        [self _resendMessage:model];
    }
    
}

第四步

EaseMessageViewController.h 滑动到 1442 行,将 didReceiveMessages 替换成以下代码

- (void) _didReceiveMessages:(EMMessage *)message {
    [self addMessageToDataSource:message progress:nil];
    
    [self _sendHasReadResponseForMessages:@[message]
                                   isRead:NO];
    
    if ([self _shouldMarkMessageAsRead])
    {
        [self.conversation markMessageAsReadWithId:message.messageId error:nil];
    }
}
// hook 这里
- (void)didReceiveMessages:(NSArray *)aMessages
{
    for (EMMessage *message in aMessages) {
        if ([self.conversation.conversationId isEqualToString:message.conversationId]) {
            
            //判断该消息是否需要截断
            if ([self.delegate respondsToSelector:@selector(messageViewController:willReceiveMessage:resultBlock:)]) {
                __weak typeof(self) weakself = self;
                [self.delegate messageViewController:self willReceiveMessage:message resultBlock:^(BOOL isDataRight) {
                    //判断是否需要接受该数据
                    if (isDataRight) {
                        [weakself _didReceiveMessages:message];
                    }
                }];
            } else {
                // 如果没有实现该代理,则不会更改源码的流程
                [self _didReceiveMessages:message];
            }
        }
    }
}

通过以上四步,便可以在消息发送或接收前将消息截取下来,再通过protocol,返回到我们自己的控制器进行管理

最后在自己的 Controller 内,便可以将发送的消息与自己服务器的数据关联起来,实现对 EaseUI 的优化

// MARK: -EaseMessageViewControllerDelegate
func messageViewController(_ viewController: EaseMessageViewController!, willSend message: EMMessage!, resultBlock block: ((Bool) -> Void)!) {
     checkAccountCorrect(hx_account: message.conversationId) { (value) in
         block(value)
     }
}
    
func messageViewController(_ viewController: EaseMessageViewController!, willReceive message: EMMessage!, resultBlock block: ((Bool) -> Void)!) {
     checkAccountCorrect(hx_account: message.conversationId) { (value) in
         block(value)
     }
}

ps:方法 checkAccountCorrect 的内容主要与我们自己的服务器交互校验数据


本人能力有限,如果有什么更好的方法或者建议,欢迎指正

你可能感兴趣的:(iOS)