拦截消息
拦截消息
IMKit SDK 可在消息发送前、发送后、接收时进行拦截。
消息拦截功能提供以下协议:
- RCIMMessageInterceptor(要求 SDK ≧ 5.3.5):支持在发送前、发送后拦截消息,可获取消息对象(RCMessage)。
RCIMSendMessageDelegate
(已废弃):支持在发送前、发送后拦截消息,但仅可获取RCMessage 的content
字段,即 RCMessageContent 或 RCMediaMessageContent 的子类对象。从 SDK 5.3.5 版本开始废弃。- RCIMReceiveMessageDelegate:支持在实时收到消息时进行拦截。
IMKit 的会话页面(RCConversationViewController)也提供与消息相关的回调方法,可用于拦截消息。详见会话页面的页面事件监听。
在消息发送前后拦截消息(SDK ≧ 5.3.5)
通过 RCIMMessageInterceptor
协议提供的回调方法,App 可以拦截待发送和已发送的消息,可获取 RCMessage 对象。
在消息发送前、后进行拦截,可能的适用场景如下:
- 在发送前拦截并修改
RCMessage
,后续由 SDK 继续发送(注意,如果 5.3.5 ≦ SDK < 5.4.5,这种方式仅支持修改RCMessage
的content
字段;如果 SDK ≧ 5.4.5,支持修改RCMessage
)。返回NO
表示 App 需要拦截,但需要 SDK 发送修改后的RCMessage
。 - 在发送前拦截并修改
RCMessage
,后续由 App 再次发送。这种方式支持修改RCMessage
。返回YES
表示 App 需要拦截并自行处理后续流程。App 需要在处理完毕后自行发送修改后的消息。 - 在发送前拦截
RCMessage
,将媒体消息中的文件上传至 App 指定的文件服务器,后续由 App 再次发送。返回YES
表示 App 需要拦截并自行处理后续流程。注意,App 需要调用上传文件到自定义服务器的发送消息方法。详见发送消息。 - 在发送后进行拦截,可修改数据库中
RCMessage
对象的部分属性,例如消息的附加信息setMessageExtra
。详见 RCCoreClient 或 RCChannelClient 中的设置方法。注意,您可能需要先检查被拦截消息的发送状态(RCMessage.sentStatus
),再判断下一步如何处理。
设置代理委托
只需全局设置一次即可,多次设置会导致其他代理失效。
[RCIM sharedRCIM].messageInterceptor = self;
已复制
1
实现此功能需要开发者遵守 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;
}
已复制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
拦截接收的消息
IMKit 的接收消息监听协议 RCIMReceiveMessageDelegate 中提供了接收消息时的拦截方法。
代理设置方法详见消息监听。设置代理委托后,实现如下方法。返回 YES
表示需要拦截接收到的消息,拦截后不再触发接收消息的回调。
@protocol RCIMReceiveMessageDelegate <NSObject>
/*!
当 Kit 收到消息回调的方法
@param message 接收到的消息
@return YES 拦截,不显示 ; NO: 不拦截, 显示此消息。
*/
- (BOOL)interceptMessage:(RCMessage *)message;
@end
已复制
1
2
3
4
5
6
7
8
9
10
11
只处理接收消息后是否在界面上是否显示。如果重新加载会话页面,消息仍会显示。如有需要,可删除该消息。详见删除消息。
在消息发送前后拦截消息(已废弃)
从 SDK 5.3.5 版本开始废弃 RCIMSendMessageDelegate
协议。
当 IMKit 在发送消息时,开发者可以通过代理监听拦截消息,开发者只需全局设置一次即可,多次设置会导致其他代理失效。
实现此功能需要开发者遵守 RCIMSendMessageDelegate 协议。
设置代理委托:
[RCIM sharedRCIM].sendMessageDelegate = self;
已复制
1
如果开发者在聊天页面拦截消息,也可以使用 RCConversationViewController 中的 willSendMessage:
方法和 didSendMessage:content:
方法。