跳到主要内容

拦截消息

IMKit SDK 可在消息发送前、发送后、接收时进行拦截。

消息拦截功能提供以下协议:

提示

IMKit 的会话页面(RCConversationViewController)也提供与消息相关的回调方法,可用于拦截消息。详见会话页面的页面事件监听

在消息发送前后拦截消息(SDK ≧ 5.3.5)

通过 RCIMMessageInterceptor 协议提供的回调方法,App 可以拦截待发送和已发送的消息,可获取 RCMessage 对象。

在消息发送前、后进行拦截,可能的适用场景如下:

  • 在发送前拦截并修改 RCMessage,后续由 SDK 继续发送(注意,如果 5.3.5 ≦ SDK < 5.4.5,这种方式仅支持修改 RCMessagecontent 字段;如果 SDK ≧ 5.4.5,支持修改 RCMessage)。返回 NO 表示 App 需要拦截,但需要 SDK 发送修改后的 RCMessage
  • 在发送前拦截并修改 RCMessage,后续由 App 再次发送。这种方式支持修改 RCMessage。返回 YES 表示 App 需要拦截并自行处理后续流程。App 需要在处理完毕后自行发送修改后的消息。
  • 在发送前拦截 RCMessage,将媒体消息中的文件上传至 App 指定的文件服务器,后续由 App 再次发送。返回 YES 表示 App 需要拦截并自行处理后续流程。注意,App 需要调用上传文件到自定义服务器的发送消息方法。详见发送消息
  • 在发送后进行拦截,可修改数据库中 RCMessage 对象的部分属性,例如消息的附加信息 setMessageExtra。详见 RCCoreClientRCChannelClient 中的设置方法。注意,您可能需要先检查被拦截消息的发送状态(RCMessage.sentStatus),再判断下一步如何处理。

设置代理委托

只需全局设置一次即可,多次设置会导致其他代理失效。

[RCIM sharedRCIM].messageInterceptor = self;

实现此功能需要开发者遵守 RCIMMessageInterceptor 协议。

#pragma mark -- RCIMMessageInterceptor

- (BOOL)interceptWillSendMessage:(RCMessage *)message {
if ([message.content isKindOfClass:[RCCombineMessage class]]) {
// 示例1:拦截合并转发消息,由 APP 负责发送
[[RCIM sharedRCIM] sendMediaMessage:message pushContent:nil pushData:nil uploadPrepare:^(RCUploadMediaStatusListener *uploadListener) {

RCCombineMessage *msgContent = (RCCombineMessage *)uploadListener.currentMessage.content;
msgContent.remoteUrl = @"https://your_file_server.com.com/test.html";
uploadListener.successBlock(msgContent);

} progress:nil successBlock:nil errorBlock:nil cancel:nil];
// 返回 YES,SDK 不会继续发送,需要您自己调用发送
return YES;
}
else if ([message.content isKindOfClass:[RCImageMessage class]]) {
// 示例2.1:过滤不需要拦截的图片消息,条件按需自定义
RCImageMessage *msgContent = (RCImageMessage *)message.content;
if ([msgContent.remoteUrl containsString:@"your_file_server"]) {
// 图片已经上传到 App File Server,不需要拦截
return NO;
}

// 示例2.2:拦截图片消息,由 APP 负责发送
[[RCIM sharedRCIM] sendMediaMessage:message pushContent:nil pushData:nil uploadPrepare:^(RCUploadMediaStatusListener *uploadListener) {

RCImageMessage *msgContent = (RCImageMessage *)uploadListener.currentMessage.content;
// 去实现自己上传附件
// 获取到上传的 url 地址, 并赋值给 remoteUrl
msgContent.remoteUrl = @"http://your_file_server.com/test.jpg";
uploadListener.successBlock(msgContent);

} progress:nil successBlock:nil errorBlock:nil cancel:nil];

// 返回 YES,SDK 不会继续发送,需要您自己调用发送
return YES;
}

else if ([message.content isKindOfClass:[RCTextMessage class]]) {
// 示例3:拦截并继续使用 SDK 方法发送,只做文本消息内容更新
RCTextMessage *msgContent = (RCTextMessage *)message.content;
msgContent.content = @"文本内容被替换了";

// 返回 NO, 继续使用 SDK 方法发送
return NO;
}


return NO;
}

拦截接收的消息

IMKit 的接收消息监听协议 RCIMReceiveMessageDelegate 中提供了接收消息时的拦截方法。

代理设置方法详见消息监听。设置代理委托后,实现如下方法。返回 YES 表示需要拦截接收到的消息,拦截后不再触发接收消息的回调。

@protocol RCIMReceiveMessageDelegate <NSObject>

/*!
当 Kit 收到消息回调的方法
@param message 接收到的消息
@return YES 拦截,不显示 ; NO: 不拦截, 显示此消息。
*/

- (BOOL)interceptMessage:(RCMessage *)message;

@end
提示

只处理接收消息后是否在界面上是否显示。如果重新加载会话页面,消息仍会显示。如有需要,可删除该消息。详见删除消息

在消息发送前后拦截消息(已废弃)

提示

从 SDK 5.3.5 版本开始废弃 RCIMSendMessageDelegate 协议。

当 IMKit 在发送消息时,开发者可以通过代理监听拦截消息,开发者只需全局设置一次即可,多次设置会导致其他代理失效。

实现此功能需要开发者遵守 RCIMSendMessageDelegate 协议。

设置代理委托:

[RCIM sharedRCIM].sendMessageDelegate = self;
提示

如果开发者在聊天页面拦截消息,也可以使用 RCConversationViewController 中的 willSendMessage: 方法和 didSendMessage:content: 方法。