--- title: 自定义消息类型 sidebar_position: 110 --- # 自定义消息类型 除了使用 SDK 内置消息外,还可以创建自定义消息类型。 您需要根据业务需求来选择自定义消息类型继承的消息基类: - `RCMessageContent`,即普通类型消息内容。例如在 SDK 内置消息类型中的文本消息和位置消息。 - `RCMediaMessageContent`,即多媒体类型消息。多媒体类型消息内容继承自 `RCMessageContent`,并在其基础上增加了对多媒体文件的处理逻辑。在发送和接收消息时,SDK 会判断消息类型是否为多媒体类型消息,如果是多媒体类型,则会触发上传或下载多媒体文件流程。 关于消息实体类与消息内容的更多介绍,可参见[消息介绍](./introduction.md)。 ## 创建自定义消息类型 自定义消息类型类遵守下面三个协议: - 编解码协议(必须遵守):`RCMessageCoding` 指定消息类型名称、消息收发过程中的编码与解码行为,以及提供消息搜索所需的关键词。该协议是所有自定义消息类型必须实现的协议,否则将无法正常传输和使用。 - 存储协议(必须遵守):`RCMessagePersistentCompatible` 指定此消息类型在客户端与服务端是否计入未读消息数、是否存储的行为。 - 内容摘要协议(非必须遵守):`RCMessageContentView` 设置如何显示该类型消息的摘要。 ### 编解码协议 :::tip 任何自定义消息类型都必须实现 `RCMessageCoding` 协议,否则将无法正常传输和使用。 ::: **协议原型**: ```objectivec @protocol RCMessageCoding ``` 编解码协议(`RCMessageCoding`)主要有以下功能: - 提供该自定义消息类型的唯一 ID。 - 在消息发送时,将消息中的所有信息编码为 JSON 数据传输。 - 在消息接收时,将 JSON 数据解码还原为消息对象。 - 提供消息搜索数据。 遵守编解码协议需实现下面的方法: - **序列化**:消息内容通过此方法,将消息中的所有数据,编码成为 JSON 数据,返回的 JSON 数据将用于网络传输。 ```objectivec - (NSData *)encode; ``` - **反序列化**:网络传输的 JSON 数据,会通过此方法解码,获取消息内容中的所有数据,生成有效的消息内容。 ```objectivec - (void)decodeWithData:(NSData *)data; ``` - **定义消息类型名**:定义的消息类型名,需要在各个平台上保持一致,否则消息无法互通。为避免和 SDK 默认的消息类型名称冲突,请勿使用 `RC:` 开头的类型名。 ```objectivec + (NSString *)getObjectName; ``` - **提供消息搜索数据**:如果需要自定义消息需要被搜索,需要将关键字返回。如果不需要被搜索,可直接返回 nil。 ```objectivec - (NSArray *)getSearchableWords; ``` ### 存储协议 存储协议(`RCMessagePersistentCompatible`)为必须遵守的协议。 **协议原型**: ```objectivec @protocol RCMessagePersistentCompatible ``` 存储协议主要有两个功能: - 指明此消息类型在本地和服务端是否存储 - 指明此消息类是否计入未读消息数 遵守存储协议需实现控制**消息的存储计数策略**的方法: ```objectivec + (RCMessagePersistent)persistentFlag; ``` | persistentFlag 属性说明 | 客户端是否存储 | 服务端是否存储 | 是否计入消息未读数 | |:----|:---|:---|:---| | MessagePersistent_NONE | 客户端不存储 | 支持离线消息?机制 | 不计入未读消息数 | | MessagePersistent_ISCOUNTED | 客户端存储 | 支持离线消息?机制,且存入服务端历史消息 | 计入未读消息数 | | MessagePersistent_ISPERSISTED | 客户端存储 | 支持离线消息?机制,且存入服务端历史消息 |不计入未读消息数 | | MessagePersistent_STATUS | 客户端不存储 | 服务端不存储 |不计入未读消息数 | :::tip - `MessagePersistent_NONE` 一般用于需要确保收到,但不需要展示的消息,例如运营平台向终端发送的指令信息。如果消息接收方不在线,再次上线时可通过离线消息收到。 - `MessagePersistent_STATUS` 用于状态消息。状态消息表示的是即时的状态,例如输入状态。因为状态消息在客户端与服务端均不会存储,如果接收方不在线,则无法再收到该状态消息。 ::: ### 内容摘要协议 内容摘要协议(`RCMessageContentView`)为非必须遵守的协议。 **协议原型**: ```objectivec @protocol RCMessageContentView ``` 消息的内容摘要显示在以下几处: - 在会话列表中 - 本地通知中 遵守内容摘要协议需实现**设置消息摘要**的方法: ```objectivec - (NSString *)conversationDigest; ``` ## 注册自定义的消息类型 在进行完自定义消息类后,需要在 SDK init 之后 connect 之前,注册此自定义消息类。 :::tip 只有注册了该消息类型之后,SDK 才能正确识别和编码、解码该类型的消息。 ::: ```objectivec - (void)registerMessageType:(Class)messageClass; ``` ## 发送自定义消息 自定义消息类型可直接使用发送内置消息类型的方法。请注意根据当前使用的 SDK、业务、消息类型选择合适的核心类与方法: - 如果自定义消息类型继承 `RCMessageContent`,请使用发送普通消息的接口发送。 - 如果自定义消息类型继承 `RCMediaMessageContent`,请使用发送媒体消息的接口发送。 如果自定义消息类型需要支持推送,必须在发送自定义消息时额外指定推送内容(`pushContent`)。推送内容在接收方收到推送时显示在通知栏中。 - 在发送消息时,可直接通过 `pushContent` 参数指定推送内容。 - 您也可以通过设置 [RCMessage] 的 `messagePushConfig` 中的 `pushContent` 及其他字段,对消息的推送进行个性化配置。优先使用 `messagePushConfig` 中的配置。详见[配置消息的推送属性]。 发送消息的具体方法与配置方式,请参考以下文档: - **App 仅集成 IMLib SDK**:[发送消息][imlib-发送消息](单聊、群聊、聊天室)、[收发消息](超级群) - **App 集成 IMKit SDK**:[发送消息][imkit-发送消息](单聊、群聊、聊天室) :::tip - 如果融云服务端无法获取自定义消息的 `pushContent`,则无法触发消息推送。例如,在接收方在离线等情况无法收到消息推送通知。 - 如果自定义的消息类型为**状态消息**(`MessagePersistent_STATUS`),则无法支持推送,不需要额外指定推送内容。 ::: ## 实例 [自定义消息范例](https://github.com/rongcloud/sealtalk-ios/tree/master/ios-sealtalk/RCloudMessage/Sections/Demo/TestMessage) [RCMessage]: https://doc.rongcloud.cn/apidoc/imlibcore-ios/latest/zh_CN/documentation/rongimlibcore/rcmessage?language=objc [imlib-发送消息]: ./send.md [imkit-发送消息]: /ios-imkit/customization/message-send [收发消息]: ../ultragroup/chat.md [配置消息的推送属性]: ../message/send.md#配置消息的推送属性