iOS 环信消息撤回发送透传消息的一些坑

来源:互联网 发布:java 模拟按键 编辑:程序博客网 时间:2024/04/30 14:58

MARK:最近做了环信的消息回撤功能,遇到一些坑,mark下。

首先,未说明哪些为环信内部保留字段。消息回撤功能环信提供的方法是发送透传消息,在创建透传消息时,用到了两个宏定义字段:

/** * 发送回撤cmd消息 * * @param message 待撤销的消息 */+ (void)sendRevokeCMDMessage:(EMMessage *)message{    EMChatCommand *command = [[EMChatCommand alloc] init];    command.cmd = KEM_REVOKE;    EMCommandMessageBody *body = [[EMCommandMessageBody alloc] initWithChatObject:command];    EMMessage *msg = [[EMMessage alloc] initWithReceiver:message.conversationChatter                                                  bodies:@[body]];    msg.messageType = message.messageType;    msg.ext = @{KEM_REVOKE_MESSAGEID:message.messageId};    [[EaseMob sharedInstance].chatManager asyncSendMessage:msg                                                  progress:nil];}
这里有两个宏定义字符串,KEM_REVOKE 和 KEM_REVOKE_MESSAGEID ,环信原文件默认的是

/** @brief 待发送消息撤销的CMD消息action */#define KEM_REVOKE                  @"em_revoke"/** @brief 消息回撤cmd扩展字段,对应的value值为待撤销消息id */#define KEM_REVOKE_MESSAGEID        @"em_revoke_messageId"
注意:em开头的这两个key是环信内部保留字段,使用时要自己替换下,如tgj_revoke,否则,你会收不到透传消息!


第二,环信聊天代理的多次添加。在进入聊天界面,打断点监听- (void)didReceiveMessages:(NSArray *)aMessages方法时,发现反复进入聊天界面几次,此方法会多次调用,每接收一条消息,此方法会重复跑几次。是因为,在dealloc方法中[[EMClient sharedClient].chatManager removeDelegate:self];移除聊天管理代理的方法并没有生效,再次进入聊天界面,有添加了一次代理,就会造成多次回调接收消息的方法。

解决方法:每次在进入界面时,先移除代理,再添加代理;界面消失时移除代理。

- (void)viewWillAppear:(BOOL)animated{    [super viewWillAppear:animated];        [self registerEaseMobDelegate];}- (void)viewWillDisappear:(BOOL)animated{    [super viewWillDisappear:animated];        [self unRegisterEaseMobDelegate];}// 向sdk中注册回调- (void)registerEaseMobDelegate{    // 此处先取消一次,是为了保证只将self注册过一次回调。    [self unRegisterEaseMobDelegate];    [[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil];}// 取消sdk中注册的回调- (void)unRegisterEaseMobDelegate{    [[EMClient sharedClient].chatManager removeDelegate:self];}

第三,据安卓同事称,安卓那边透传消息在环信退出重登后,收不到。这会导致在对方下线的情况下,消息回撤不了。因为对方就没收到透传消息。不知是安卓真的收不到还是没有调好,iOS退出重登后是可以收到离线期间的透传消息的。为了两端兼容,最终我们换了另一种方法去撤回消息。(改用:点击撤回发送一条带扩展消息的普通消息,扩展消息包含需要撤回的消息id,接收到之后删除本条消息以及扩展里指定的消息)