iOS IMLib SDK 开发指南

    在您阅读此文档之前,我们假定您已经具备了基础的 iOS 应用开发经验,并阅读了新手指南

    IMLib 快速集成

    您可以阅读前期准备文档,了解注册开发者账号、创建应用、下载与导入 SDK 的具体步骤。

    如果您已经阅读了上面的文档内容,并准备好工程和 AppKey 相关事宜,则可以参考本章节内容,快速便捷的集成融云即时通讯绝大部分功能(启动会话列表,进入会话,发送文本、语音、图片、位置消息等)。

    本章节将介绍如何将 IMLib 快速集成到您的 App。

    SDK Swift 使用说明

    使用 Swift 语言快速集成融云即时通讯功能,只需要生成一个 您的工程模块名-Bridging-Header.h 文件,在其中加入 SDK 的引用即可。

    #import <RongIMLib/RongIMLib.h>
    

    更多内容,可以参考 Apple 文档

    工程准备

    您在尝试集成 SDK 的时候,为了方便,可以新建一个工程。并参考 iOS IMKit 开发指南中的“下载与导入 SDK”,在工程中导入了 SDK 并设置了各种库依赖。

    初始化

    在您需要使用融云 SDK 功能的类中,import 相关头文件。

    #import <RongIMLib/RongIMLib.h>
    

    如果是 Swift 的话,需要在您工程的 Bridging-Header.h 文件中加入 SDK 的引用。

    #import <RongIMLib/RongIMLib.h>
    

    请使用您之前从融云开发者控制台注册得到的 App Key,通过RCIM的单例,传入 initWithAppKey: 方法,初始化 SDK。 您在使用融云 SDK 所有功能(包括显示 SDK 中的 View 或者显示继承于 SDK 的 View )之前,您必须先调用此方法初始化 SDK。 在 App 的整个生命周期中,您只需要将 SDK 初始化一次。

    [[RCIMClient sharedRCIMClient] initWithAppKey:@"YourTestAppKey"];
    

    获取 Token

    Token 即用户令牌,相当于您 APP 上当前用户连接融云的身份凭证。 在您连接融云服务器之前,您需要请求您的 App Server,您的 App Server 通过 Server API 获取 Token 并返回给您的客户端,客户端获取到这个 Token 即可进入下一步连接融云服务器。

    为什么必须在服务器端请求 Token,客户端不提供获取 Token 的接口?

    因为获取 Token 时需要提供 App KeyApp Secret 。如果在客户端请求 Token,假如您的 App 代码一旦被反编译,则会导致您的 App Key 和 App Secret 泄露。所以,务必在您的服务器端获取 Token。

    我们在开发者控制台提供了 API 调试的功能,在开发初期阶段,您可以通过其中获取 Token 功能,手动获取 Token 进行测试。

    连接服务器

    将您在上一步获取到的 Token,通过 RCIMClient 的单例,传入 -connectWithToken:success:error:tokenIncorrect: 方法,即可建立与服务器的连接。

    在 App 整个生命周期,您只需要调用一次此方法与融云服务器建立连接。之后无论是网络出现异常或者 App 有前后台的切换等,SDK 都会负责自动重连。 SDK 针对 iOS 的前后台和各种网络状况,进行了连接和重连机制的优化,建议您调用一次 connectWithToken 即可,其余交给 SDK 处理。 除非您已经手动将连接断开,否则您不需要自己再手动重连。

    [[RCIMClient sharedRCIMClient] connectWithToken:@"YourTestUserToken"
                                            success:^(NSString *userId) {
                                                NSLog(@"登陆成功。当前登录的用户ID:%@", userId);
                                            } error:^(RCConnectErrorCode status) {
                                                NSLog(@"登陆的错误码为:%d", status);
                                            } tokenIncorrect:^{
                                                //token过期或者不正确。
                                                //如果设置了token有效期并且token过期,请重新请求您的服务器获取新的token
                                                //如果没有设置token有效期却提示token错误,请检查您客户端和服务器的appkey是否匹配,还有检查您获取token的流程。
                                                NSLog(@"token错误");
                                            }];
    

    发送与接收消息

    连接服务器成功之后,您就可以收发消息了,下面以文本消息为例,说明消息的收发。

    发送一条文本消息:

    // 构建消息的内容,这里以文本消息为例。
    RCTextMessage *testMessage = [RCTextMessage messageWithContent:@"test"];
    // 调用RCIMClient的sendMessage方法进行发送,结果会通过回调进行反馈。
    [[RCIMClient sharedRCIMClient] sendMessage:ConversationType_PRIVATE
                                      targetId:userId
                                       content:testMessage
                                   pushContent:nil
                                      pushData:nil
                                       success:^(long messageId) {
                                           NSLog(@"发送成功。当前消息ID:%@", messageId);
                                       } error:^(RCErrorCode nErrorCode, long messageId) {
                                           NSLog(@"发送失败。消息ID:%@, 错误码:%d", messageId, nErrorCode);
                                       }];
    

    您可以通过设置来监听接收到的消息。

    // 设置消息接收监听
    [[RCIMClient sharedRCIMClient] setReceiveMessageDelegate:self object:nil];
    

    监听消息接收:

    /*!
     接收消息的回调方法
    
     @param message     当前接收到的消息
     @param nLeft       还剩余的未接收的消息数,left>=0
     @param object      消息监听设置的key值
    
     @discussion 如果您设置了IMlib消息监听之后,SDK在接收到消息时候会执行此方法。
     其中,left为还剩余的、还未接收的消息数量。比如刚上线一口气收到多条消息时,通过此方法,您可以获取到每条消息,left会依次递减直到0。
     您可以根据left数量来优化您的App体验和性能,比如收到大量消息时等待left为0再刷新UI。
     object为您在设置消息接收监听时的key值。
     */
    - (void)onReceived:(RCMessage *)message
                  left:(int)nLeft
                object:(id)object {
        if ([message.content isMemberOfClass:[RCTextMessage class]]) {
            RCTextMessage *testMessage = (RCTextMessage *)message.content;
            NSLog(@"消息内容:%@", testMessage.content);
        }
    
        NSLog(@"还剩余的未接收的消息数:%d", nLeft);
    }
    

    获取未读数

    您可以通过以下代码获取当前所有的未读消息数。

    int totalUnreadCount = [[RCIMClient sharedRCIMClient] getTotalUnreadCount];
    NSLog(@"当前所有会话的未读消息数为:%d", totalUnreadCount);
    

    您也可以获取具体会话或某些类型的未读消息数,以及清空未读消息数。

    // RCIMClient Class
    
    /*!
     获取某个会话内的未读消息数
    
     @param conversationType    会话类型
     @param targetId            会话目标ID
     @return                    该会话内的未读消息数
     */
    - (int)getUnreadCount:(RCConversationType)conversationType
                 targetId:(NSString *)targetId;
    
    /*!
     获取某个类型的会话中所有的未读消息数
    
     @param conversationTypes   会话类型的数组
     @return                    该类型的会话中所有的未读消息数
     */
    - (int)getUnreadCount:(NSArray *)conversationTypes;
    
    /*!
     清除某个会话中的未读消息数
    
     @param conversationType    会话类型,不支持聊天室
     @param targetId            目标会话ID
     @return                    是否清除成功
     */
    - (BOOL)clearMessagesUnreadStatus:(RCConversationType)conversationType
                             targetId:(NSString *)targetId;
    

    获取会话列表

    您可以通过以下代码获取本地存储的会话列表。

    NSArray *conversationList = [[RCIMClient sharedRCIMClient]
                              getConversationList:@[@(ConversationType_PRIVATE),
                                                    @(ConversationType_DISCUSSION),
                                                    @(ConversationType_GROUP),
                                                    @(ConversationType_SYSTEM),
                                                    @(ConversationType_APPSERVICE),
                                                    @(ConversationType_PUBLICSERVICE)]];
    for (RCConversation *conversation in conversationList) {
        NSLog(@"会话类型:%lu,目标会话ID:%@", (unsigned long)conversation.conversationType, conversation.targetId);
    }
    

    您也可以获取指定的会话。

    //RCIMClient Class
    
    /*!
     获取单个会话数据
    
     @param conversationType    会话类型
     @param targetId            目标会话ID
     @return                    会话的对象
     */
    - (RCConversation *)getConversation:(RCConversationType)conversationType
                               targetId:(NSString *)targetId;
    

    IMLib 进阶指南

    消息接口

    消息实体与消息内容

    消息实体(RCMessage)是本地存储的实体对象,其中包含消息的各种属性(如消息 ID、消息的方向、接收状态、接收时间、发送者等)与消息内容。

    消息内容(RCMessageContent)是与消息属性无关的一段 json 数据,可以承载任何内容。

    融云 SDK 针对 IM 的使用场景,内置了常用类型的消息(如文本消息、图片消息、语音消息、位置消息、富文本消息等)。您也可以自定义消息,在消息内容中传输和存储任何json格式的内容。 消息在本地存储是以消息实体(RCMessage)的形式存在,在传输时以内容(RCMessageContent)的形式存在。

    发送消息

    SDK 针对普通消息、图片消息(上传到融云默认的图片服务器)、状态消息等提供了三类接口。

    // RCIMClient Class
    
    /*!
     发送消息
    
     @param conversationType    发送消息的会话类型
     @param targetId            发送消息的目标会话ID
     @param content             消息的内容
     @param pushContent         接收方离线时需要显示的远程推送内容
     @param pushData            接收方离线时需要在远程推送中携带的非显示数据
     @param successBlock        消息发送成功的回调 [messageId:消息的ID]
     @param errorBlock          消息发送失败的回调 [nErrorCode:发送失败的错误码, messageId:消息的ID]
     @return                    发送的消息实体
    
     @discussion 当接收方离线并允许远程推送时,会收到远程推送。
     远程推送中包含两部分内容,一是pushContent,用于显示;二是pushData,用于携带不显示的数据。
    
     SDK内置的消息类型,如果您将pushContent和pushData置为nil,会使用默认的推送格式进行远程推送。
     自定义类型的消息,需要您自己设置pushContent和pushData来定义推送内容,否则将不会进行远程推送。
    
     如果您使用此方法发送图片消息,需要您自己实现图片的上传,构建一个RCImageMessage对象,
     并将RCImageMessage中的imageUrl字段设置为上传成功的URL地址,然后使用此方法发送。
    
     @warning 如果您使用IMLib,可以使用此方法发送消息;
     如果您使用IMKit,请使用RCIM中的同名方法发送消息,否则不会自动更新UI。
     */
    - (RCMessage *)sendMessage:(RCConversationType)conversationType
                      targetId:(NSString *)targetId
                       content:(RCMessageContent *)content
                   pushContent:(NSString *)pushContent
                      pushData:(NSString *)pushData
                       success:(void (^)(long messageId))successBlock
                         error:(void (^)(RCErrorCode nErrorCode, long messageId))errorBlock;
    
    /*!
     发送图片消息
    
     @param conversationType    发送消息的会话类型
     @param targetId            发送消息的目标会话ID
     @param content             消息的内容
     @param pushContent         接收方离线时需要显示的远程推送内容
     @param pushData            接收方离线时需要在远程推送中携带的非显示数据
     @param progressBlock       消息发送进度更新的回调 [progress:当前的发送进度, 0 <= progress <= 100, messageId:消息的ID]
     @param successBlock        消息发送成功的回调 [messageId:消息的ID]
     @param errorBlock          消息发送失败的回调 [errorCode:发送失败的错误码, messageId:消息的ID]
     @return                    发送的消息实体
    
     @discussion 当接收方离线并允许远程推送时,会收到远程推送。
     远程推送中包含两部分内容,一是pushContent,用于显示;二是pushData,用于携带不显示的数据。
    
     SDK内置的消息类型,如果您将pushContent和pushData置为nil,会使用默认的推送格式进行远程推送。
     自定义类型的消息,需要您自己设置pushContent和pushData来定义推送内容,否则将不会进行远程推送。
    
     如果您需要上传图片到自己的服务器,构建一个RCImageMessage对象,
     并将RCImageMessage中的imageUrl字段设置为上传成功的URL地址,然后使用RCIMClient的
     sendMessage:targetId:content:pushContent:pushData:success:error:方法
     或sendMessage:targetId:content:pushContent:success:error:方法进行发送,不要使用此方法。
    
     @warning 如果您使用IMKit,使用此方法发送图片消息SDK会自动更新UI;
     如果您使用IMLib,请使用RCIMClient中的同名方法发送图片消息,不会自动更新UI。
     */
    - (RCMessage *)sendImageMessage:(RCConversationType)conversationType
                           targetId:(NSString *)targetId
                            content:(RCMessageContent *)content
                        pushContent:(NSString *)pushContent
                           pushData:(NSString *)pushData
                           progress:(void (^)(int progress, long messageId))progressBlock
                            success:(void (^)(long messageId))successBlock
                              error:(void (^)(RCErrorCode errorCode, long messageId))errorBlock;
    
    /*!
     发送状态消息
    
     @param conversationType    会话类型
     @param targetId            目标会话ID
     @param content             消息内容
     @param successBlock        发送消息成功的回调 [messageId:消息的ID]
     @param errorBlock          发送消息失败的回调 [nErrorCode:发送失败的错误码, messageId:消息的ID]
    
     @discussion 通过此方法发送的消息,根据接收方的状态进行投递。
     如果接收方不在线,则不会收到远程推送,再上线也不会收到此消息。
     */
    - (RCMessage *)sendStatusMessage:(RCConversationType)conversationType
                            targetId:(NSString *)targetId
                             content:(RCMessageContent *)content
                             success:(void (^)(long messageId))successBlock
                               error:(void (^)(RCErrorCode nErrorCode, long messageId))errorBlock;
    
    注:融云 SDK 中默认将图片上传到七牛云存储,图片有效期为 1 个月
    如果您需要上传图片到自己的服务器,构建一个 RCImageMessage 对象, 并将 RCImageMessage 中的 imageUrl 字段设置为上传成功的 URL 地址,然后使用 RCIMClientsendMessage:targetId:content:pushContent:pushData:success:error: 方法 或 sendMessage:targetId:content:pushContent:success:error: 方法进行发送。

    插入消息

    您也可以只在本地存储中插入一条消息,但是不向外发送。

    //RCIMClient Class
    
    /*!
     插入消息
    
     @param conversationType    会话类型
     @param targetId            目标会话ID
     @param senderUserId        消息发送者的用户ID
     @param sendStatus          发送状态
     @param content             消息的内容
     @return                    插入的消息实体
    
     @discussion 此方法不支持聊天室的会话类型。
    
     @warning 目前仅支持插入向外发送的消息,不支持插入接收的消息。
     */
    - (RCMessage *)insertMessage:(RCConversationType)conversationType
                        targetId:(NSString *)targetId
                    senderUserId:(NSString *)senderUserId
                      sendStatus:(RCSentStatus)sendStatus
                         content:(RCMessageContent *)content;
    

    读取本地存储消息

    // RCIMClient Class
    
    /*!
     获取某个会话中指定数量的最新消息实体
    
     @param conversationType    会话类型
     @param targetId            目标会话ID
     @param count               需要获取的消息数量
     @return                    消息实体RCMessage对象列表
    
     @discussion 此方法会获取该会话中指定数量的最新消息实体,返回的消息实体按照时间从新到旧排列。
     如果会话中的消息数量小于参数count的值,会将该会话中的所有消息返回。
     */
    - (NSArray *)getLatestMessages:(RCConversationType)conversationType
                          targetId:(NSString *)targetId
                             count:(int)count;
    
    /*!
     获取会话中,从指定消息之前、指定数量的最新消息实体
    
     @param conversationType    会话类型
     @param targetId            目标会话ID
     @param oldestMessageId     截止的消息ID
     @param count               需要获取的消息数量
     @return                    消息实体RCMessage对象列表
    
     @discussion 此方法会获取该会话中,oldestMessageId之前的、指定数量的最新消息实体,返回的消息实体按照时间从新到旧排列。
     返回的消息中不包含oldestMessageId对应那条消息,如果会话中的消息数量小于参数count的值,会将该会话中的所有消息返回。
     如:
     oldestMessageId为10,count为2,会返回messageId为9和8的RCMessage对象列表。
     */
    - (NSArray *)getHistoryMessages:(RCConversationType)conversationType
                           targetId:(NSString *)targetId
                    oldestMessageId:(long)oldestMessageId
                              count:(int)count;
    
    /*!
     获取会话中,从指定消息之前、指定数量的、指定消息类型的最新消息实体
    
     @param conversationType    会话类型
     @param targetId            目标会话ID
     @param objectName          消息内容的类型名
     @param oldestMessageId     截止的消息ID
     @param count               需要获取的消息数量
     @return                    消息实体RCMessage对象列表
    
     @discussion 此方法会获取该会话中,oldestMessageId之前的、指定数量和消息类型的最新消息实体,返回的消息实体按照时间从新到旧排列。
     返回的消息中不包含oldestMessageId对应的那条消息,如果会话中的消息数量小于参数count的值,会将该会话中的所有消息返回。
     如:
     oldestMessageId为10,count为2,会返回messageId为9和8的RCMessage对象列表。
     */
    -(NSArray*)getHistoryMessages:(RCConversationType)conversationType
                         targetId:(NSString*)targetId
                       objectName:(NSString *)objectName
                  oldestMessageId:(long)oldestMessageId
                            count:(int)count;
    

    读取远程服务器的单群聊消息

    提供单聊、群聊、讨论组、客服的历史消息获取,您每次可以从服务器获取之前 20 条以内的消息历史记录(需要先开通历史消息云存储功能),最多获取前 6 个月的历史消息。

    // RCIMClient Class
    
    /*!
     从服务器端获取之前的历史消息
    
     @param conversationType    会话类型,不支持聊天室会话类型
     @param targetId            目标会话ID
     @param recordTime          最早的发送时间,第一次可以传0
     @param count               需要获取的消息数量, 0< count <= 20
     @param successBlock        获取成功的回调 [messages:获取到的历史消息数组]
     @param errorBlock          获取失败的回调 [status:获取失败的错误码]
    
     @discussion 此方法从服务器端获取之前的历史消息,但是必须先开通历史消息云存储功能。
     */
    - (void)getRemoteHistoryMessages:(RCConversationType)conversationType
                            targetId:(NSString *)targetId
                          recordTime:(long)recordTime
                               count:(int)count
                             success:(void (^)(NSArray *messages))successBlock
                               error:(void (^)(RCErrorCode status))errorBlock;
    

    读取远程服务器的聊天室消息

    开通聊天室消息存储功能后,融云内置的文字、语音、图片、图文、位置、文件等消息会自动在服务器端进行存储,如果您的聊天室中用到了自定义类消息,可通过定义 MessageTag.ISPERSISTED 来设置消息是否进行存储。

    从服务器端获取聊天室历史消息的接口如下:

    /*!
     从服务器端获取聊天室的历史消息
     @param targetId            聊天室ID
     @param recordTime       起始的消息发送时间戳,毫秒
     @param count               需要获取的消息数量, 0 < count <= 200
     @param order               拉取顺序,RC_Timestamp_Desc:倒序,RC_Timestamp_ASC:正序
     @param successBlock   获取成功的回调 [messages:获取到的历史消息数组, syncTime:下次拉取消息的时间戳]
     @param errorBlock        获取失败的回调 [status:获取失败的错误码]
     @discussion
     此方法从服务器端获取聊天室的历史消息,但是必须先开通聊天室消息云存储功能。
     指定开始时间,比如2016年9月1日10点(1472695200000), 默认是0(正序:从存储的第一条消息开始拉取,倒序:从存储的最后一条消息开始拉取)
     */
    - (void)getRemoteChatroomHistoryMessages:(NSString *)targetId
                                  recordTime:(long long)recordTime
                                       count:(int)count
                                       order:(RCTimestampOrder)order
                                     success:(void (^)(NSArray *messages, long long syncTime))successBlock
                                       error:(void (^)(RCErrorCode status))errorBlock;
    

    删除消息

    // RCIMClient Class
    
    /*!
     删除消息
    
     @param messageIds  消息ID的列表
     @return            是否删除成功
     */
    - (BOOL)deleteMessages:(NSArray *)messageIds;
    
    /*!
     删除某个会话中的所有消息
    
     @param conversationType    会话类型,不支持聊天室
     @param targetId            目标会话ID
     @return                    是否删除成功
     */
    - (BOOL)clearMessages:(RCConversationType)conversationType
                 targetId:(NSString *)targetId;
    

    设置消息的状态

    //RCIMClient Class
    
    /*!
     设置消息的接收状态
    
     @param messageId       消息ID
     @param receivedStatus  消息的接收状态
     @return                是否设置成功
     */
    - (BOOL)setMessageReceivedStatus:(long)messageId
                      receivedStatus:(RCReceivedStatus)receivedStatus;
    
    /*!
     设置消息的发送状态
    
     @param messageId       消息ID
     @param sentStatus      消息的发送状态
     @return                是否设置成功
     */
    - (BOOL)setMessageSentStatus:(long)messageId
                      sentStatus:(RCSentStatus)sentStatus;
    

    语音消息

    出于平台兼容和网络优化的考虑,iOS 在语音消息录制的时候使用 WAV 格式录制,由 WAV 数据生成 RCVoiceMessageRCVoiceMessage 中的音频会转为 AMR-NB 格式的音频并进行 base64 编码后进行传输。

    您可以使用以下参数(单声道、采样率为 8000Hz、位宽为 16 位)录制语音。

    NSDictionary *settings = @{AVFormatIDKey: @(kAudioFormatLinearPCM),
                               AVSampleRateKey: @8000.00f,
                               AVNumberOfChannelsKey: @1,
                               AVLinearPCMBitDepthKey: @16,
                               AVLinearPCMIsNonInterleaved: @NO,
                               AVLinearPCMIsFloatKey: @NO,
                               AVLinearPCMIsBigEndianKey: @NO};
    

    然后使用 wav 数据初始化 RCVoiceMessage

    // RCVoiceMessage class
    
    /*!
     初始化语音消息
    
     @param audioData   wav格式的音频数据
     @param duration    语音消息的时长
     @return            语音消息对象
    
     @discussion 如果您不是使用IMKit中的录音功能,则在初始化语音消息的时候,需要确保以下几点。
     1. audioData必须是单声道的wav格式音频数据;
     2. audioData的采样率必须是8000Hz,位宽必须为16位。
    
     您可以参考IMKit中的录音参数:
     NSDictionary *settings = @{AVFormatIDKey: @(kAudioFormatLinearPCM),
                                AVSampleRateKey: @8000.00f,
                                AVNumberOfChannelsKey: @1,
                                AVLinearPCMBitDepthKey: @16,
                                AVLinearPCMIsNonInterleaved: @NO,
                                AVLinearPCMIsFloatKey: @NO,
                                AVLinearPCMIsBigEndianKey: @NO};
     */
    + (instancetype)messageWithAudio:(NSData *)audioData
                            duration:(long)duration;
    

    因为 iOS 4 之后的系统不再支持直接播放 AMR 音频,您可以直接使用 wavAudioData 字段,即可获得可播放的 WAV 数据(SDK 在 getter 时会自动将存储的 AMR 数据编码为 WAV)。

    // RCVoiceMessage class
    
    /*!
     wav格式的音频数据
     */
    @property(nonatomic, strong) NSData *wavAudioData;
    
    建议语音消息时长最小为 1 秒,最长不能超过 60 秒。
    如果默认的音频参数不能满足您的需求,您可以通过自定义消息的定制。

    图片消息

    您在构建 RCImageMessage 并发送时,默认会根据您提供的图片,生成缩略图。 缩略图尺寸为:240 x 240 像素,以宽度和高度中较长的边不超过 240 像素等比压缩。

    // RCImageMessage class
    
    /*!
     初始化图片消息
    
     @param image   原始图片
     @return        图片消息对象
     */
    + (instancetype)messageWithImage:(UIImage *)image;
    
    /*!
     初始化图片消息
    
     @param imageURI    图片的本地路径
     @return            图片消息对象
     */
    + (instancetype)messageWithImageURI:(NSString *)imageURI;
    

    如果您不设置为发送时使用原图的话,默认会将最长边超过 960 像素的图片进行压缩。 压缩的大图尺寸为:960 x 960 像素,以宽度和高度中较长的边不超过 960 像素等比压缩。

    // RCImageMessage class
    
    /*!
     是否发送原图
    
     @discussion 在发送图片的时候,是否发送原图,默认值为NO。
     */
    @property(nonatomic, getter=isFull) BOOL full;
    

    文件消息

    文件消息类

    文件消息类 RCFileMessage.h ,您可以使用类方法构造文件消息,注意使用的路径必须是文件的本地路径,类方法及参数说明如下:

    /*!
    文件消息的objectName
    */
    #define RCFileMessageTypeIdentifier @"RC:FileMsg"
    
    /*!
    文件名
    */
    @property(nonatomic, strong) NSString *name;
    
    /*!
    文件大小,单位为Byte
    */
    @property(nonatomic, assign) long long size;
    
    /*!
    文件类型
    */
    @property(nonatomic, strong) NSString *type;
    
    /*!
    文件的网络地址
    */
    @property(nonatomic, strong) NSString *fileUrl;
    
    /*!
    文件的本地路径
    */
    @property(nonatomic, strong) NSString *localPath;
    
    /*!
    附加信息
    */
    @property(nonatomic, strong) NSString *extra;
    
    /*!
    初始化文件消息
    @param localPath 文件的本地路径
    @return          文件消息对象
    */
    + (instancetype)messageWithFile:(NSString *)localPath;
    

    发送文件消息

    可以将构造好的文件消息使用下面两种方法进行发送:

    • SDK 默认将文件上传到七牛服务器,发送中的 progress 回调可以监听到文件发送进度。
    /*!
    发送媒体消息(图片消息或文本消息)
    
    @param conversationType    发送消息的会话类型
    @param targetId            发送消息的目标会话ID
    @param content             消息的内容
    @param pushContent         接收方离线时需要显示的远程推送内容
    @param pushData            接收方离线时需要在远程推送中携带的非显示数据
    @param progressBlock       消息发送进度更新的回调 [progress:当前的发送进度, 0
    <= progress <= 100, messageId:消息的ID]
    @param successBlock        消息发送成功的回调 [messageId:消息的ID]
    @param errorBlock          消息发送失败的回调 [errorCode:发送失败的错误码,
    messageId:消息的ID]
    @return                    发送的消息实体
    
    @discussion 当接收方离线并允许远程推送时,会收到远程推送。
    远程推送中包含两部分内容,一是 pushContent,用于显示;二是 pushData,用于携带不显示的数据。
    
    SDK 内置的消息类型,如果您将 pushContent 和 pushData 置为 nil,会使用默认的推送格式进行远程推送。
    自定义类型的消息,需要您自己设置 pushContent 和 pushData 来定义推送内容,否则将不会进行远程推送。
    
    如果您需要上传图片到自己的服务器,需要构建一个 RCImageMessage 对象,
    并将 RCImageMessage 中的 imageUrl 字段设置为上传成功的URL地址,然后使用 RCIMClient 的
    sendMessage:targetId:content:pushContent:pushData:success:error:方法
    或sendMessage:targetId:content:pushContent:success:error:方法进行发送,不要使用此方法。
    
    如果您需要上传文件到自己的服务器,构建一个 RCFileMessage 对象,
    并将 RCFileMessage 中的 fileUrl 字段设置为上传成功的 URL 地址,然后使用 RCIMClient 的
    sendMessage:targetId:content:pushContent:pushData:success:error:方法
    或sendMessage:targetId:content:pushContent:success:error:方法进行发送,不要使用此方法。
    @warning 如果您使用 IMKit,使用此方法发送媒体消息 SDK 会自动更新UI;
    如果您使用 IMLib,请使用 RCIMClient 中的同名方法发送媒体消息,不会自动更新UI。
    */
    - (RCMessage *)sendMediaMessage:(RCConversationType)conversationType
    targetId:(NSString *)targetId
    content:(RCMessageContent *)content
    pushContent:(NSString *)pushContent
    pushData:(NSString *)pushData
    progress:(void (^)(int progress, long messageId))progressBlock
    success:(void (^)(long messageId))successBlock
    error:(void (^)(RCErrorCode errorCode, long messageId))errorBlock;
    
    • 将文件上传到指定服务器,发送中的 progress 回调可以监听到文件发送进度。
    /*!
    发送媒体消息(上传图片或文件等媒体信息到指定的服务器)
    
    @param conversationType    发送消息的会话类型
    @param targetId            发送消息的目标会话ID
    @param content             消息的内容
    @param pushContent         接收方离线时需要显示的远程推送内容
    @param pushData            接收方离线时需要在远程推送中携带的非显示数据
    @param uploadPrepareBlock  媒体文件上传进度更新的IMKit监听
    [uploadListener:当前的发送进度监听,SDK通过此监听更新IMKit UI]
    @param progressBlock       消息发送进度更新的回调 [progress:当前的发送进度, 0
    <= progress <= 100, messageId:消息的ID]
    @param successBlock        消息发送成功的回调 [messageId:消息的ID]
    @param errorBlock          消息发送失败的回调 [errorCode:发送失败的错误码,
    messageId:消息的ID]
    @return                    发送的消息实体
    
    @discussion 此方法仅用于IMKit。
    如果您需要上传图片到自己的服务器并使用IMLib,构建一个RCImageMessage对象,
    并将RCImageMessage中的imageUrl字段设置为上传成功的URL地址,然后使用RCIMClient的
    sendMessage:targetId:content:pushContent:pushData:success:error:方法
    或sendMessage:targetId:content:pushContent:success:error:方法进行发送,不要使用此方法。
    
    如果您需要上传文件到自己的服务器并使用IMLib,构建一个RCFileMessage对象,
    并将RCFileMessage中的fileUrl字段设置为上传成功的URL地址,然后使用RCIMClient的
    sendMessage:targetId:content:pushContent:pushData:success:error:方法
    或sendMessage:targetId:content:pushContent:success:error:方法进行发送,不要使用此方法。
    */
    - (RCMessage *)sendMediaMessage:(RCConversationType)conversationType
    targetId:(NSString *)targetId
    content:(RCMessageContent *)content
    pushContent:(NSString *)pushContent
    pushData:(NSString *)pushData
    uploadPrepare:(void (^)(RCUploadMediaStatusListener *uploadListener))uploadPrepareBlock
    progress:(void (^)(int progress, long messageId))progressBlock
    success:(void (^)(long messageId))successBlock
    error:(void (^)(RCErrorCode errorCode, long messageId))errorBlock;
    

    下载文件

    收到文件消息后,可使用 downloadMediaMessage 方法下载文件消息,当下载中, progress 的回调可以监听下载进度。当下载成功,在 success 的回调中可以获取到文件下载到本地后的路径。

    /*!
    下载消息内容中的媒体信息
    
    @param messageId           媒体消息的messageId
    @param progressBlock       消息下载进度更新的回调 [progress:当前的下载进度, 0 <= progress <= 100]
    @param successBlock        下载成功的回调[mediaPath:下载成功后本地存放的文件路径]
    @param errorBlock          下载失败的回调[errorCode:下载失败的错误码]
    @param cancelBlock         用户取消了下载的回调
    */
    - (void)downloadMediaMessage:(long)messageId
    progress:(void (^)(int progress))progressBlock
    success:(void (^)(NSString *mediaPath))successBlock
    error:(void (^)(RCErrorCode errorCode))errorBlock
    cancel:(void (^)())cancelBlock;
    

    取消下载

    下载过程中,可以使用 cancelDownloadMediaMessage 方法取消文件下载。

    /*!
    取消下载消息中的媒体信息
    
    @param messageId           媒体消息的messageId
    
    @return true取消成功。false下载完成或者下载不存在
    */
    - (BOOL)cancelDownloadMediaMessage:(long)messageId;
    

    本地消息搜索

    通过关键字搜索指定会话的本地消息,目前只支持文本消息、文件消息、图文消息的本地搜索功能。

    /*!
     根据关键字搜索指定会话中的消息
    
     @param conversationType 会话类型
     @param targetId         会话ID
     @param keyword          关键字
     @param count            最大的查询数量
     @param startTime        查询记录的起始时间(传 0 表示不限时间)
    
     @return 匹配的消息列表
     */
    - (NSArray <RCMessage *>*)searchMessages:(RCConversationType)conversationType
                                    targetId:(NSString *)targetId
                                     keyword:(NSString *)keyword
                                       count:(int)count
                                   startTime:(long long)startTime;
    
    /*!
     根据关键字搜索会话
    
     @param conversationTypeList 需要搜索的会话类型列表
     @param objectNameList       需要搜索的消息类型名列表(即每个消息类方法getObjectName的返回值)
     @param keyword              关键字
    
     @return 匹配的会话搜索结果列表
    
     @discussion 目前,SDK 内置的文本消息、文件消息、图文消息支持搜索。
     自定义的消息必须要实现RCMessageContent的getSearchableWords接口才能进行搜索。
     */
    - (NSArray<RCSearchConversationResult *> *)searchConversations:
                                                   (NSArray<NSNumber *> *)conversationTypeList
                                                       messageType:(NSArray<NSString *> *)objectNameList
                                                           keyword:(NSString *)keyword;
    

    会话接口

    会话

    会话实体类 RCConversation 是本地存储的会话对象,其中主要包含几类属性:通道相关(conversationTypetargetId)、存储和显示相关(isTopunreadMessageCountconversationTitledraft等)、会话中的最后一条消息相关(lastestMessageIdlastestMessagereceivedStatus 等)。

    读取本地存储的会话

    // RCIMClient Class
    
    /*!
     获取会话列表
    
     @param conversationTypeList    会话类型的数组(需要将RCConversationType转为NSNumber构建Array)
     @return                        会话RCConversation的列表
    
     @discussion 此方法会从本地数据库中,读取会话列表。
     返回的会话列表按照时间从前往后排列,如果有置顶的会话,则置顶的会话会排列在前面。
     */
    - (NSArray *)getConversationList:(NSArray *)conversationTypeList;
    
    /*!
     获取单个会话数据
    
     @param conversationType    会话类型
     @param targetId            目标会话ID
     @return                    会话的对象
     */
    - (RCConversation *)getConversation:(RCConversationType)conversationType
                               targetId:(NSString *)targetId;
    

    删除本地存储的会话

    // RCIMClient Class
    
    /*!
     删除指定类型的会话
    
     @param conversationTypeList    会话类型的数组(需要将RCConversationType转为NSNumber构建Array)
     @return                        是否删除成功
     */
    - (BOOL)clearConversations:(NSArray *)conversationTypeList;
    
    /*!
     从本地存储中删除会话
    
     @param conversationType    会话类型
     @param targetId            目标会话ID
     @return                    是否删除成功
    
     @discussion 此方法会从本地存储中删除该会话,但是不会删除会话中的消息。
     */
    - (BOOL)removeConversation:(RCConversationType)conversationType
                      targetId:(NSString *)targetId;
    

    设置置顶

    // RCIMClient Class
    
    /*!
     设置会话的置顶状态
    
     @param conversationType    会话类型
     @param targetId            目标会话ID
     @param isTop               是否置顶
     @return                    设置是否成功
     */
    - (BOOL)setConversationToTop:(RCConversationType)conversationType
                        targetId:(NSString *)targetId
                           isTop:(BOOL)isTop;
    

    会话的草稿

    您可以将用户未发送的消息内容作为草稿保存在本地。目前仅支持 NSString 类型,您也可以通过保存 json 数据的方法保存任意格式的草稿。

    // RCIMClient Class
    
    /*!
     获取会话中的草稿信息
    
     @param conversationType    会话类型
     @param targetId            会话目标ID
     @return                    该会话中的草稿
     */
    - (NSString *)getTextMessageDraft:(RCConversationType)conversationType
                             targetId:(NSString *)targetId;
    
    /*!
     保存草稿信息
    
     @param conversationType    会话类型
     @param targetId            会话目标ID
     @param content             草稿信息
     @return                    是否保存成功
     */
    - (BOOL)saveTextMessageDraft:(RCConversationType)conversationType
                        targetId:(NSString *)targetId
                         content:(NSString *)content;
    
    /*!
     删除会话中的草稿信息
    
     @param conversationType    会话类型
     @param targetId            会话目标ID
     @return                    是否删除成功
     */
    - (BOOL)clearTextMessageDraft:(RCConversationType)conversationType
                         targetId:(NSString *)targetId;
    

    会话的消息提醒状态

    您可以针对会话设置屏蔽消息提醒,也可以按时间段进行设置。

    // RCIMClient Class
    
    /*!
     设置会话的消息提醒状态
    
     @param conversationType            会话类型
     @param targetId                    目标会话ID
     @param isBlocked                   是否屏蔽消息提醒
     @param successBlock                设置成功的回调 [nStatus:会话设置的消息提醒状态]
     @param errorBlock                  设置失败的回调 [status:设置失败的错误码]
    
     @discussion 如果您使用IMLib,此方法会屏蔽该会话的远程推送;如果您使用IMKit,此方法会屏蔽该会话的所有提醒(远程推送、本地通知、前台提示音)。
     */
    - (void)setConversationNotificationStatus:(RCConversationType)conversationType
                                     targetId:(NSString *)targetId
                                    isBlocked:(BOOL)isBlocked
                                      success:(void (^)(RCConversationNotificationStatus nStatus))successBlock
                                        error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     查询会话的消息提醒状态
    
     @param conversationType    会话类型
     @param targetId            目标会话ID
     @param successBlock        查询成功的回调 [nStatus:会话设置的消息提醒状态]
     @param errorBlock          查询失败的回调 [status:设置失败的错误码]
     */
    - (void)getConversationNotificationStatus:(RCConversationType)conversationType
                                     targetId:(NSString *)targetId
                                      success:(void (^)(RCConversationNotificationStatus nStatus))successBlock
                                        error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     屏蔽会话在某个时间段的消息提醒
    
     @param startTime       开始屏蔽消息提醒的时间,格式为HH:MM:SS
     @param spanMins        需要屏蔽消息提醒的分钟数,0 < spanMins < 1440
     @param successBlock    屏蔽成功的回调
     @param errorBlock      屏蔽失败的回调 [status:屏蔽失败的错误码]
    
     @discussion 此方法设置的屏蔽时间会在每天该时间段时生效。
     如果您使用IMLib,此方法会屏蔽该会话在该时间段的远程推送;如果您使用IMKit,此方法会屏蔽该会话在该时间段的所有提醒(远程推送、本地通知、前台提示音)。
     */
    - (void)setConversationNotificationQuietHours:(NSString *)startTime
                                         spanMins:(int)spanMins
                                          success:(void (^)())successBlock
                                            error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     删除会话的时间段消息提醒的屏蔽设置
    
     @param successBlock    删除屏蔽成功的回调
     @param errorBlock      删除屏蔽失败的回调 [status:失败的错误码]
     */
    - (void)removeConversationNotificationQuietHours:(void (^)())successBlock
                                               error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     查询会话消息提醒的屏蔽时间段设置
    
     @param successBlock    屏蔽成功的回调 [startTime:已设置的屏蔽开始时间, spansMin:已设置的屏蔽时间分钟数,0 < spansMin < 1440]
     @param errorBlock      查询失败的回调 [status:查询失败的错误码]
     */
    - (void)getNotificationQuietHours:(void (^)(NSString *startTime, int spansMin))successBlock
                                error:(void (^)(RCErrorCode status))errorBlock;
    

    正在输入的状态提醒

    您可以在用户正在输入的时候,向对方发送正在输入的状态。 其中,您可以在 contentType 中传入消息的类型名,会话中的其他用户输入状态回执中会收到此消息类型,您可以通过此消息类型,自定义不同的输入状态提示(如:正在输入、正在讲话、正在拍摄等)。

    6 秒之内,如果同一个用户在同一个会话中多次调用此接口发送正在输入的状态,为保证产品体验和网络优化,将只有最开始的一次生效。

    // RCIMClient Class
    
    /*!
     向会话中发送正在输入的状态
    
     @param conversationType    会话类型
     @param targetId            会话目标ID
     @param contentType         正在输入的消息的类型名
    
     @discussion contentType为用户当前正在编辑的消息类型名,即RCMessageContent中getObjectName的返回值。
     如文本消息,应该传类型名"RC:TxtMsg"。
    
     @warning 目前仅支持单聊。
     */
    - (void)sendTypingStatus:(RCConversationType)conversationType
                    targetId:(NSString *)targetId
                 contentType:(NSString *)objectName;
    

    在接收端,您可以通过设置输入状态的监听器。 当任何会话中任何用户输入状态有变化的时候,都会回调此接口。您可以通过此回调获取到当前时刻正在输入的所有用户以及正在输入的消息类型,而无需维护之前的用户状态。

    // RCIMClient Class
    
    /*!
     设置输入状态的监听器
    
     @param delegate IMLib输入状态的的监听器
    
     @warning 目前仅支持单聊。
     */
    - (void)setRCTypingStatusDelegate:(id<RCTypingStatusDelegate>)delegate;
    
    /*!
     IMLib输入状态的的监听器
    
     @discussion 设置IMLib的输入状态监听器,请参考RCIMClient的setRCTypingStatusDelegate:方法。
    
     @warning 如果您使用IMLib,可以设置并实现此Delegate监听消息接收;
     如果您使用IMKit,请直接设置RCIM中的enableSendComposingStatus,而不要使用此监听器,否则会导致IMKit中无法自动更新UI!
     */
    @protocol RCTypingStatusDelegate <NSObject>
    
    /*!
     用户输入状态变化的回调
    
     @param conversationType        会话类型
     @param targetId                会话目标ID
     @param userTypingStatusList    正在输入的RCUserTypingStatus列表(nil标示当前没有用户正在输入)
    
     @discussion 当客户端收到用户输入状态的变化时,会回调此接口,通知发生变化的会话以及当前正在输入的RCUserTypingStatus列表。
    
     @warning 目前仅支持单聊。
     */
    - (void)onTypingStatusChanged:(RCConversationType)conversationType
                         targetId:(NSString *)targetId
                           status:(NSArray *)userTypingStatusList;
    
    @end
    

    目前,输入状态提醒的功能仅支持单聊。

    群组、讨论组 @ 功能

    从 2.6.8 版本开始,群组、讨论组中支持 @ 消息功能,满足您 @ 指定用户或 @ 所有人的需求,在 RCMessageContent 类中新增 @ 属性,如下:

    /*!
    消息中的@提醒信息
    */
    @property(nonatomic, strong) RCMentionedInfo *mentionedInfo;
    

    RCMentionInfo 定义如下:

    /*!
    消息中的 @ 提醒信息
    */
    @interface RCMentionedInfo : NSObject
    
    /*!
    @提醒的类型,设置 @ 指定用户,还是 @ 所有人
    */
    @property(nonatomic, assign) RCMentionedType type;
    
    /*!
    @的用户ID列表
    
    @discussion 如果 type 是 @所有人,则可以传 nil
    */
    @property(nonatomic, strong) NSArray *userIdList;
    
    /*!
    包含 @ 提醒的消息,本地通知和远程推送显示的内容
    */
    @property(nonatomic, strong) NSString *mentionedContent;
    
    /*!
    初始化 @ 提醒信息
    
    @param type       @提醒的类型
    @param userIdList @的用户 ID 列表
    
    @return @提醒信息的对象
    */
    - (instancetype)initWithMentionedType:(RCMentionedType)type
    userIdList:(NSArray *)userIdList
    mentionedContent:(NSString *)mentionedContent;
    

    RCMentionedType 定义如下:

    #pragma mark RCMediaType - 消息中@提醒的类型
    /*!
     @提醒的类型
     */
    typedef NS_ENUM(NSUInteger, RCMentionedType) {
       /*!
       @所有人
       */
       RC_Mentioned_All = 1,
    
       /*!
       @部分指定用户
       */
       RC_Mentioned_Users = 2,
    };
    

    在发送消息的时候如果需要 @ 提示,可以给消息的 mentionedInfo 赋值。示例:

    RCTextMessage *rcTextMessage = [RCTextMessage messageWithContent:@“Test”];
    
    rcTextMessage.mentionedInfo = [[RCMentionedInfo alloc] initWithMentionedType:RC_Mentioned_Users userIdList:mentionedUserIdList mentionedContent:nil];
    
    [self sendMessage:rcTextMessage pushContent:nil];
    

    收到 @ 消息时,在 RCConversation 里新增标示 hasUnreadMentioned

    /*!
    会话中是否存在被@的消息
    
    @discussion 在清除会话未读数(clearMessagesUnreadStatus:targetId:)的时候,会将此状态置成 NO。
    */
    @property(nonatomic, assign) BOOL hasUnreadMentioned;
    
    @ 消息推送会越过所有免打扰逻辑,给用户推送 Push 通知。
    如果是自定义消息,在使用 @ 功能时,发送消息必须设置 pushContent ,否则不会发送 Push 。

    消息撤回

    从 2.6.8 版本开始,支持消息撤回功能。调用 RCIMClient.h 中的 recallMessage 接口撤回已发送的消息,撤回成功后,该消息在数据库中将被替换成 RCRecallNotificationMessage ,您需要在成功回调里重新加载这条数据,刷新聊天界面。

    /*!
     撤回消息
    
     @param message      需要撤回的消息
     @param successBlock 撤回成功的回调 [messageId:撤回的消息ID,该消息已经变更为新的消息]
     @param errorBlock   撤回失败的回调 [errorCode:撤回失败错误码]
     */
    - (void)recallMessage:(RCMessage *)message
                  success:(void (^)(long messageId))successBlock
                    error:(void(^)(RCErrorCode errorcode))errorBlock;
    

    接收方,收到的消息被发送者撤回后,被撤回的消息在数据库中将被替换成 RCRecallNotificationMessage ,并触发以下方法,可在该方法中进行相关操作并刷新聊天界面。

    /*!
     消息被撤回的回调方法
    
     @param messageId 被撤回的消息ID
    
     @discussion 被撤回的消息会变更为RCRecallNotificationMessage,App需要在UI上刷新这条消息。
     */
    -(void)onMessageRecalled:(long)messageId;
    

    消息阅读回执

    单聊消息阅读回执

    您可以在用户查看了单聊会话中的未读消息之后,向会话中发送已读回执,会话中的用户可以根据此回执,在 UI 中更新消息的显示。 其中,time 为会话中用户已经阅读的最后一条消息的发送时间戳(RCMessagesentTime 属性),代表用户已经阅读了该会话中此消息之前的所有消息。

    // RCIMClient Class
    
    /*!
     发送某个会话中消息阅读的回执
    
     @param conversationType    会话类型
     @param targetId            目标会话ID
     @param timestamp           该会话中已阅读的最后一条消息的发送时间戳
    
     @discussion 此接口目前只支持单聊, 如果使用Lib 可以注册监听 RCLibDispatchReadReceiptNotification 通知,使用kit 直接开启RCIM.h 中enableReadReceipt。
    
     @warning 此接口目前仅支持单聊。
     */
    -(void)sendReadReceiptMessage:(RCConversationType)conversationType
                         targetId:(NSString *)targetId
                             time:(long long)timestamp;
    

    在接收端,您可以监听已读回执的 Notification 来更新消息的相关显示。

    // RCIMClient Class
    
    /*!
     @const 收到已读回执的 Notification
    
     @discussion 收到消息已读回执之后,IMLib 会分发此通知。
    
     Notification 的 object 为 nil,userInfo 为 NSDictionary 对象,
     其中 key 值分别为 @"cType"、@"tId"、@"messageTime",
     对应的 value 为会话类型的 NSNumber 对象、会话的 targetId、已阅读的最后一条消息的 sendTime。
     如:
     NSNumber *ctype = [notification.userInfo objectForKey:@"cType"];
     NSNumber *time = [notification.userInfo objectForKey:@"messageTime"];
     NSString *targetId = [notification.userInfo objectForKey:@"tId"];
    
     收到这个消息之后可以更新这个会话中 messageTime 以前的消息 UI 为已读(底层数据库消息状态已经改为已读)。
    
     */
    FOUNDATION_EXPORT NSString *const RCLibDispatchReadReceiptNotification;
    

    群组、讨论组消息阅读回执

    在 RCIMClient.h 中提供了消息阅读回执及未读数同步相关功能接口:

    1、群组消息请求回执,对于需要阅读之后收到阅读回执的消息,可以调用这个接口来发送阅读回执请求。

    - (void)sendReadReceiptRequest:(RCConversationType)conversationType
                                 targetId:(NSString *)targetId
                                  message:(RCMessage *)message
                                  success:(void (^)())successBlock
                                    error:(void (^)(RCErrorCode nErrorCode))errorBlock;
    
    
    注:接收方需要设置实现RCIMClientReceiveMessageDelegate
      /*!
     请求消息已读回执(收到需要阅读时发送回执的请求,收到此请求后在会话页面已经展示该 messageUId 对应的消息或者调用 getHistoryMessages 获取消息的时候,包含此 messageUId 的消息,需要调用
     sendMessageReadReceiptResponse 接口发送消息阅读回执)
     */
    - (void)onMessageReceiptRequest:(RCConversationType)conversationType targetId:(NSString *)targetId messageUId:(NSString *)messageUId;
    

    2、已读回执,当收到阅读回执请求的时候,展现消息后可以调用此接口来发送消息阅读回执。

    - (void)sendReadReceiptResponse:(RCConversationType)conversationType
                                  targetId:(NSString *)targetId
                               messageList:(NSArray<RCMessage *> *)messageList
                                   success:(void (^)())successBlock
                                     error:(void (^)(RCErrorCode nErrorCode))errorBlock;
    
    注:接收方需要设置实现RCIMClientReceiveMessageDelegate
    /*!
     消息已读回执响应(收到阅读回执响应,可以按照 messageUId 更新消息的阅读数)
     @param messageUId 已读回执的消息ID
     */
    - (void)onMessageReceiptResponse:(RCConversationType)conversationType targetId:(NSString *)targetId messageUId:(NSString *)messageUId readerList:(NSMutableDictionary *)userIdList;
    

    调用 syncConversationReadStatus 方法,同步多端会话已读状态,详细请查看多端阅读消息数同步

    RCMessage.h 中设置消息阅读回执功能属性:

    /*!
     阅读回执状态
     */
    @property(nonatomic, strong) RCReadReceiptInfo *readReceiptInfo;
    
    
    ### 新增类 RCReadReceiptInfo.h
    /*!
     是否需要回执消息
     */
    @property(nonatomic, assign) BOOL isReceiptRequestMessage;
    
    /**
     *  是否已经发送回执
     */
    @property(nonatomic,assign) BOOL hasRespond;
    
    /*!
     发送回执的用户ID列表
     */
    @property(nonatomic, strong) NSMutableDictionary *userIdList;
    

    多端阅读消息数同步

    同步会话已读状态,点击进入会话或者退出会话的时候可以调用这个方法,同一个帐号在其它端登录会收到通知 RCLibDispatchReadReceiptNotification

    - (void)syncConversationReadStatus:(RCConversationType)conversationType
                         targetId:(NSString *)targetId
                             time:(long long)timestamp
                          success:(void (^)())successBlock
                            error:(void (^)(RCErrorCode nErrorCode))errorBlock;
    

    黑名单

    您可以将用户加入、移出黑名单,也可以查询当前已经设置的黑名单。

    // RCIMClient Class
    
    /*!
     将某个用户加入黑名单
    
     @param userId          需要加入黑名单的用户ID
     @param successBlock    加入黑名单成功的回调
     @param errorBlock      加入黑名单失败的回调 [status:失败的错误码]
     */
    - (void)addToBlacklist:(NSString *)userId
                   success:(void (^)())successBlock
                     error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     将某个用户移出黑名单
    
     @param userId          需要移出黑名单的用户ID
     @param successBlock    移出黑名单成功的回调
     @param errorBlock      移出黑名单失败的回调[status:失败的错误码]
     */
    - (void)removeFromBlacklist:(NSString *)userId
                        success:(void (^)())successBlock
                          error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     查询某个用户是否已经在黑名单中
    
     @param userId          需要查询的用户ID
     @param successBlock    查询成功的回调 [bizStatus:该用户是否在黑名单中。0表示已经在黑名单中,101表示不在黑名单中]
     @param errorBlock      查询失败的回调 [status:失败的错误码]
     */
    - (void)getBlacklistStatus:(NSString *)userId
                       success:(void (^)(int bizStatus))successBlock
                         error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     查询已经设置的黑名单列表
    
     @param successBlock    查询成功的回调 [blockUserIds:已经设置的黑名单中的用户ID列表]
     @param errorBlock      查询失败的回调 [status:失败的错误码]
     */
    - (void)getBlacklist:(void (^)(NSArray *blockUserIds))successBlock
                   error:(void (^)(RCErrorCode status))errorBlock;
    
    黑名单针对用户 ID 生效,即使换设备也依然生效。

    讨论组

    讨论组是用户自发创建的多人聊天,在客户端您可以完成讨论组的创建、加入、退出、踢人、设置等。

    // RCIMClient Class
    
    /*!
     创建讨论组
    
     @param name            讨论组名称
     @param userIdList      用户ID的列表
     @param successBlock    创建讨论组成功的回调 [discussion:创建成功返回的讨论组对象]
     @param errorBlock      创建讨论组失败的回调 [status:创建失败的错误码]
     */
    - (void)createDiscussion:(NSString *)name
                  userIdList:(NSArray *)userIdList
                     success:(void (^)(RCDiscussion *discussion))successBlock
                       error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     讨论组加人,将用户加入讨论组
    
     @param discussionId    讨论组ID
     @param userIdList      需要加入的用户ID列表
     @param successBlock    讨论组加人成功的回调 [discussion:讨论组加人成功返回的讨论组对象]
     @param errorBlock      讨论组加人失败的回调 [status:讨论组加人失败的错误码]
    
     @discussion 设置的讨论组名称长度不能超过40个字符,否则将会截断为前40个字符。
     */
    - (void)addMemberToDiscussion:(NSString *)discussionId
                       userIdList:(NSArray *)userIdList
                          success:(void (^)(RCDiscussion *discussion))successBlock
                            error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     讨论组踢人,将用户移出讨论组
    
     @param discussionId    讨论组ID
     @param userId          需要移出的用户ID
     @param successBlock    讨论组踢人成功的回调 [discussion:讨论组踢人成功返回的讨论组对象]
     @param errorBlock      讨论组踢人失败的回调 [status:讨论组踢人失败的错误码]
    
     @discussion 如果当前登陆用户不是此讨论组的创建者并且此讨论组没有开放加人权限,则会返回错误。
    
     @warning 不能使用此接口将自己移除,否则会返回错误。
     如果您需要退出该讨论组,可以使用-quitDiscussion:success:error:方法。
     */
    - (void)removeMemberFromDiscussion:(NSString *)discussionId
                                userId:(NSString *)userId
                               success:(void (^)(RCDiscussion *discussion))successBlock
                                 error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     退出当前讨论组
    
     @param discussionId    讨论组ID
     @param successBlock    退出成功的回调 [discussion:退出成功返回的讨论组对象]
     @param errorBlock      退出失败的回调 [status:退出失败的错误码]
     */
    - (void)quitDiscussion:(NSString *)discussionId
                   success:(void (^)(RCDiscussion *discussion))successBlock
                     error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     获取讨论组的信息
    
     @param discussionId    需要获取信息的讨论组ID
     @param successBlock    获取讨论组信息成功的回调 [discussion:获取的讨论组信息]
     @param errorBlock      获取讨论组信息失败的回调 [status:获取讨论组信息失败的错误码]
     */
    - (void)getDiscussion:(NSString *)discussionId
                  success:(void (^)(RCDiscussion *discussion))successBlock
                    error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     设置讨论组名称
    
     @param targetId                需要设置的讨论组ID
     @param discussionName          需要设置的讨论组名称,discussionName长度<=40
     @param successBlock            设置成功的回调
     @param errorBlock              设置失败的回调 [status:设置失败的错误码]
    
     @discussion 设置的讨论组名称长度不能超过40个字符,否则将会截断为前40个字符。
     */
    - (void)setDiscussionName:(NSString *)targetId
                         name:(NSString *)discussionName
                      success:(void (^)())successBlock
                        error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     设置讨论组是否开放加人权限
    
     @param targetId        讨论组ID
     @param isOpen          是否开放加人权限
     @param successBlock    设置成功的回调
     @param errorBlock      设置失败的回调[status:设置失败的错误码]
    
     @discussion 讨论组默认开放加人权限,即所有成员都可以加人。
     如果关闭加人权限之后,只有讨论组的创建者有加人权限。
     */
    - (void)setDiscussionInviteStatus:(NSString *)targetId
                               isOpen:(BOOL)isOpen
                              success:(void (^)())successBlock
                                error:(void (^)(RCErrorCode status))errorBlock;
    

    群组

    群组关系和群组列表由您的 App 维护,客户端的所有群组操作都需要请求您的 App Server, 您的 App Server 可以根据自己的逻辑进行管理和控制,然后通过 Server API 接口进行群组操作,并将结果返回给客户端。

    以下展示了客户端进行群组操作的流程。

    创建群组

    App -> App Server: App 向自已应用服务器发起创建群组请求。 App Server -> RongCloud Server: 授权成功后,在融云服务端同步创建群组。\n /group/create RongCloud Server -> App Server: 创建成功,返回状态。 App Server -> App: 创建成功,可以发送群组信息。

    加入群组

    App -> App Server: App 向自已应用服务器发起加入群组请求。 App Server -> RongCloud Server: 授权成功后,调用融云服务端加入群组接口。\n /group/join RongCloud Server -> App Server: 加入成功,返回状态。 App Server -> App: 加入成功,用户可在群组中发送信息。

    退出群组

    App -> App Server: App 向自已应用服务器发起退出群组请求。 App Server -> RongCloud Server: 授权成功后,调用融云服务端退出群组接口。\n /group/quit RongCloud Server -> App Server: 退出成功,返回状态。 App Server -> App: 退出群组,用户不会再收到此群组信息。

    解散群组

    App -> App Server: App 向自已应用服务器发起解散群组请求。 App Server -> RongCloud Server: 授权成功后,调用融云服务端解散群组接口。\n /group/dismiss RongCloud Server -> App Server: 解散成功,返回状态。 App Server -> App: 成功解散群组。

    设置群组信息

    App -> App Server: App 向自已应用服务器发起设置群组信息请求。 App Server -> RongCloud Server: 授权成功后,调用融云服务端设置群组信息接口。\n /group/refresh RongCloud Server -> App Server: 设置成功,返回状态。 App Server -> App: 群组信息设置成功。

    获取群组成员列表

    App -> App Server: App 向自已应用服务器发起查询群组成员请求。 App Server -> App: 成功,返回成员信息。

    获取群组列表

    App -> RongCloud Server: 连接融云服务器。 connectWithToken RongCloud Server -> App: 连接成功,返回状态信息。 App --> App Server: 请求获取群组列表 App Server -> RongCloud Server: 如有变更,需要向融云服务端同步群组信息。 RongCloud Server -> App Server: 成功,返回状态信息。 App Server --> App: 成功,返回群组列表。
    建议在登录成功之后从 App 服务器获取一次群组列表信息,以保证客户端和服务器的群组信息同步,提升用户体验。

    聊天室

    您在客户端可以加入和退出聊天室。

    // RCIMClient Class
    
    /*!
     加入聊天室
    
     @param targetId                聊天室ID
     @param messageCount            进入聊天室时获取历史消息的数量,-1<=messageCount<=50
     @param successBlock            加入聊天室成功的回调
     @param errorBlock              加入聊天室失败的回调 [status:加入聊天室失败的错误码]
    
     @discussion 可以通过传入的messageCount设置加入聊天室成功之后,需要获取的历史消息数量。
     -1表示不获取任何历史消息,0表示不特殊设置而使用SDK默认的设置(默认为获取10条),0<messageCount<=50为具体获取的消息数量,最大值为50。
     */
    - (void)joinChatRoom:(NSString *)targetId
            messageCount:(int)messageCount
                 success:(void (^)())successBlock
                   error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     退出聊天室
    
     @param targetId                聊天室ID
     @param successBlock            退出聊天室成功的回调
     @param errorBlock              退出聊天室失败的回调 [status:退出聊天室失败的错误码]
     */
    - (void)quitChatRoom:(NSString *)targetId
                 success:(void (^)())successBlock
                   error:(void (^)(RCErrorCode status))errorBlock;
    

    公众服务

    您客户端在使用公众服务之前,必须先接入公众服务。更多内容可以参考:公众服务开发文档

    您在客户端可以查找、关注、取消关注和获取相关公众账号的信息。

    如果您在后台对您的公众服务信息进行了修改,客户端在下一次连接服务器时会更新相应的信息。

    您在可以通过以下接口查找可用的公众服务。

    // RCIMClient Class
    
    /*!
     查找公众服务账号
    
     @param searchType                  查找匹配方式
     @param searchKey                   查找关键字
     @param successBlock                查找成功的回调 [accounts:查找到的公众服务账号信息RCPublicServiceProfile的数组]
     @param errorBlock                  查找失败的回调 [status:失败的错误码]
     */
    - (void)searchPublicService:(RCSearchType)searchType
                      searchKey:(NSString *)searchKey
                        success:(void (^)(NSArray *accounts))successBlock
                          error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     按类型查找公众服务账号
    
     @param publicServiceType           公众服务账号的类型
     @param searchType                  查找匹配方式
     @param searchKey                   查找关键字
     @param successBlock                查找成功的回调 [accounts:查找到的公众服务账号信息RCPublicServiceProfile的数组]
     @param errorBlock                  查找失败的回调 [status:失败的错误码]
     */
    - (void)searchPublicServiceByType:(RCPublicServiceType)publicServiceType
                           searchType:(RCSearchType)searchType
                            searchKey:(NSString *)searchKey
                              success:(void (^)(NSArray *accounts))successBlock
                                error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     查询已关注的公众服务账号
    
     @return 公众服务信息RCPublicServiceProfile列表
     */
    - (NSArray *)getPublicServiceList;
    

    您可以通过以下接口关注和取消关注某个公众服务。

    // RCIMClient Class
    
    /*!
     关注公众服务账号
    
     @param publicServiceType       公众服务账号的类型
     @param publicServiceId         公众服务的账号ID
     @param successBlock            关注成功的回调
     @param errorBlock              关注失败的回调 [status:失败的错误码]
     */
    - (void)subscribePublicService:(RCPublicServiceType)publicServiceType
                   publicServiceId:(NSString *)publicServiceId
                           success:(void (^)())successBlock
                             error:(void (^)(RCErrorCode status))errorBlock;
    
    /*!
     取消关注公众服务账号
    
     @param publicServiceType       公众服务账号的类型
     @param publicServiceId         公众服务的账号ID
     @param successBlock            取消关注成功的回调
     @param errorBlock              取消关注失败的回调 [status:失败的错误码]
     */
    - (void)unsubscribePublicService:(RCPublicServiceType)publicServiceType
                     publicServiceId:(NSString *)publicServiceId
                             success:(void (^)())successBlock
                               error:(void (^)(RCErrorCode status))errorBlock;
    

    您可以通过以下接口获取公众服务的信息。

    /*!
     获取公众服务账号信息
    
     @param publicServiceType       公众服务账号的类型
     @param publicServiceId         公众服务的账号ID
     @return                        公众服务账号的信息
    
     @discussion 此方法会从本地缓存中获取公众服务账号信息
     */
    - (RCPublicServiceProfile *)getPublicServiceProfile:(RCPublicServiceType)publicServiceType
                                        publicServiceId:(NSString *)publicServiceId;
    
    /*!
     获取公众服务账号信息
    
     @param targetId                        公众服务的账号ID
     @param type                            公众服务账号的类型
     @param onSuccess                       获取成功的回调 [serviceProfile:获取到的公众账号信息]
     @param onError                         获取失败的回调 [error:失败的错误码]
     @return                                公众服务账号的信息
    
     @discussion 此方法会从服务器获取公众服务账号信息
     */
    - (void)getPublicServiceProfile:(NSString *)targetId
                   conversationType:(RCConversationType)type
                          onSuccess:(void (^)(RCPublicServiceProfile *serviceProfile))onSuccess
                            onError:(void (^)(NSError *error))onError;
    

    当公众服务需要打开某个 URL 的时候,您可以使用以下接口生成 WebView Controller,直接显示即可。

    IMLib 生成的 WebView Controller 会自动完成必要的鉴权。
    /*!
     获取公众服务使用的WebView Controller
    
     @param URLString   准备打开的URL
     @return            公众服务使用的WebView Controller
     */
    - (UIViewController *)getPublicServiceWebViewController:(NSString *)URLString;
    

    客服

    对界面要求较高、有定制要求的用户,可以使用 IMLib 进行集成,IMLib 中客服功能集成使用说明:

    • 在进入到客服聊天界面时,调用 startCustomService:onSuccess:onError:onModeType:onQuit 来启动客服服务。
    • 根据 onModeType 的回调来处理不同的键盘输入。在机器人优先模式下,需要在界面上加上转人工的按钮。
    • onQuit 时,离开客服会话或者提示客服服务已经结束。
    • 当用户按下转人工服务时,调用 switchToHumanMode 来切换到人工服务。如果调用成功,onModeType 回调返回服务类型。
    • 当离开界面时,调用 stopCustomeService: 来结束客服。
    • 在适当的时机对客服进行评价。
    • 当 onSelectGroup 时,App 需要弹出技能组选择界面供用户选择。
    • 当用户选择技能组后,调用 selectCustomerServiceGroup:withGroupId 来启动对应技能组客服,如果用户没有选择,也必须调用 selectCustomerServiceGroup:withGroupId 来启动默认客服,groupId 此时为 nil。

    RCIMClient.h 头文件中的客服相关接口如下:

    /*!
     发起客服聊天
    
     @param kefuId       客服ID
     @param csInfo       客服信息
     @param successBlock            发起客服会话成功的回调
     @param errorBlock              发起客服会话失败的回调 [errorCode:失败的错误码 errMsg:错误信息]
     @param modeTypeBlock           客服模式变化
     @param pullEvaluationBlock     客服请求评价
     @param selectGroupBlock        客服分组选择
     @param quitBlock 客服被动结束。如果主动调用stopCustomerService,则不会调用到该block
    
     @discussion 有些客服提供商可能会主动邀请评价,有些不会,所以用lib开发客服需要注意对pullEvaluationBlock的处理。在pullEvaluationBlock里应该弹出评价。如果pullEvaluationBlock没有被调用到,需要在结束客服时(之前之后都可以)弹出评价框并评价。如果客服有分组,selectGroupBlock会被回调,此时必须让用户选择分组然后调用selectCustomerServiceGroup:withGroupId:。
    
     @warning 如果你使用IMKit,请不要使用此方法。RCConversationViewController默认已经做了处理。
     */
    - (void)
    startCustomerService:(NSString *)kefuId
                    info:(RCCustomerServiceInfo *)csInfo
               onSuccess:(void (^)(RCCustomerServiceConfig *config))successBlock
                 onError:(void (^)(int errorCode, NSString *errMsg))errorBlock
              onModeType:(void (^)(RCCSModeType mode))modeTypeBlock
        onPullEvaluation:(void (^)(NSString *dialogId))pullEvaluationBlock
           onSelectGroup:(void (^)(NSArray <RCCustomerServiceGroupItem*> *groupList))selectGroupBlock
                  onQuit:(void (^)(NSString *quitMsg))quitBlock;
    
    
    /*!
     结束客服聊天
    
     @param kefuId       客服ID
    
     @discussion 此方法依赖startCustomerService方法,只有调用成功以后才有效。
     @warning 如果你使用IMKit,请不要使用此方法。RCConversationViewController默认已经做了处理。
     */
    - (void)stopCustomerService:(NSString *)kefuId;
    
    /*!
     切换客服模式
    
     @param kefuId       客服ID
    
     @discussion 此方法依赖startCustomerService方法,而且只有当前客服模式为机器人优先才可调用。
     @warning 如果你使用IMKit,请不要使用此方法。RCConversationViewController默认已经做了处理。
     */
    - (void)switchToHumanMode:(NSString *)kefuId;
    
    /*!
     选择客服分组模式
    
     @param kefuId       客服ID
     @param groupId       选择的客服分组id
     @discussion 此方法依赖startCustomerService方法,只有调用成功以后才有效。
     @warning
     如果你使用IMKit,请不要使用此方法。RCConversationViewController默认已经做了处理。
     */
    - (void)selectCustomerServiceGroup:(NSString *)kefuId withGroupId:(NSString *)groupId;
    
    /*!
     评价机器人客服,用于对单条机器人应答的评价。
    
     @param kefuId                客服ID
     @param knownledgeId          知识点ID
     @param isRobotResolved       是否解决问题
     @param suggest                客户建议
    
     @discussion 此方法依赖startCustomerService方法。可在客服结束之前或之后调用。
     @warning 如果你使用IMKit,请不要使用此方法。RCConversationViewController默认已经做了处理。
     */
    - (void)evaluateCustomerService:(NSString *)kefuId knownledgeId:(NSString *)knownledgeId robotValue:(BOOL)isRobotResolved suggest:(NSString *)suggest;
    
    /*!
     评价人工客服。
    
     @param kefuId                客服ID
     @param dialogId              对话ID,客服请求评价的对话ID
     @param value                 分数,取值范围1-5
     @param suggest                客户建议
    
     @discussion 此方法依赖startCustomerService方法。可在客服结束之前或之后调用。
     @warning 如果你使用IMKit,请不要使用此方法。RCConversationViewController默认已经做了处理。
     */
    - (void)evaluateCustomerService:(NSString *)kefuId dialogId:(NSString *)dialogId humanValue:(int)value suggest:(NSString *)suggest;
    
    开发者后台客服使用说明,详细请参见客服使用文档

    自定义消息

    自定义消息的原理和流程

    RCMessageContent 是消息内容类,是所有消息的基类。您可以继承此类,并实现其中的协议,来实现自定义消息。

    RCMessageContent 主要有三个协议:

    1. 编解码协议 RCMessageCoding
    2. 存储协议 RCMessagePersistentCompatible
    3. 内容摘要协议 RCMessageContentView(可选)

    其中,RCMessageCoding 主要有三个功能:提供消息唯一标识符、消息发送时将消息中的所有信息编码为 json 数据传输、消息接收时将json数据解码还原为消息对象。 RCMessagePersistentCompatible 用于确定消息内容的存储策略,指明此消息类型在本地是否存储、是否计入未读消息数。 RCMessageContentView 用于在会话列表和本地通知中显示消息的摘要。

    消息发送流程:

    Client A -> Encode: 发送消息,对消息内容 RCMessageContent 做 Encode 处理 Encode -> persistentFlag: 消息是否存储 persistentFlag -> Save: 是,存储 Save -> Client B: 发送给客户端 persistentFlag -> Client B: 不存储,直接发送给客户端

    消息接收流程:

    Client A -> RongCloud Server: 发送消息 RongCloud Server -> APNS: 使用 p12 证书建立 SSL 链接 APNS --> RongCloud Server: 链接成功 RongCloud Server -> APNS: 发送消息 + deviceToken APNS -> iOS System: 远程推送 iOS System -> Client B: didFinishLaunchingWithOptions 或 didReceiveRemoteNotification

    您可以通过继承 RCMessageContent 实现其中的协议,将您的消息内容编解码为 json 数据,即可实现存放任何数据的消息。

    实现自定义消息类

    您在编写自定义消息的类时,需要实现 RCMessageCodingRCMessagePersistentCompatibleRCMessageContentView(可选)协议。

    // RCMessageContent Class
    
    /*!
     消息内容的编解码协议
    
     @discussion 用于标示消息内容的类型,进行消息的编码和解码。
     所有自定义消息必须实现此协议,否则将无法正常传输和使用。
     */
    @protocol RCMessageCoding <NSObject>
    @required
    
    /*!
     将消息内容序列化,编码成为可传输的json数据
    
     @discussion 消息内容通过此方法,将消息中的所有数据,编码成为json数据,返回的json数据将用于网络传输。
     */
    - (NSData *)encode;
    
    /*!
     将json数据的内容反序列化,解码生成可用的消息内容
    
     @param data    消息中的原始json数据
    
     @discussion 网络传输的json数据,会通过此方法解码,获取消息内容中的所有数据,生成有效的消息内容。
     */
    - (void)decodeWithData:(NSData *)data;
    
    /*!
     返回消息的类型名
    
     @return 消息的类型名
    
     @discussion 您定义的消息类型名,需要在各个平台上保持一致,以保证消息互通。
    
     @warning 请勿使用@"RC:"开头的类型名,以免和SDK默认的消息名称冲突
     */
    + (NSString *)getObjectName;
    
    @end
    
    /*!
     消息内容的存储协议
    
     @discussion 用于确定消息内容的存储策略。
     所有自定义消息必须实现此协议,否则将无法正常存储和使用。
     */
    @protocol RCMessagePersistentCompatible <NSObject>
    @required
    
    /*!
     返回消息的存储策略
    
     @return 消息的存储策略
    
     @discussion 指明此消息类型在本地是否存储、是否计入未读消息数。
     */
    + (RCMessagePersistent)persistentFlag;
    @end
    
    /*!
     消息内容摘要的协议
    
     @discussion 用于在会话列表和本地通知中显示消息的摘要。
     */
    @protocol RCMessageContentView
    @optional
    
    /*!
     返回在会话列表和本地通知中显示的消息内容摘要
    
     @return 会话列表和本地通知中显示的消息内容摘要
    
     @discussion 如果您使用IMKit,当会话的最后一条消息为自定义消息时,需要通过此方法获取在会话列表展现的内容摘要;
     当App在后台收到消息时,需要通过此方法获取在本地通知中展现的内容摘要。
     */
    - (NSString *)conversationDigest;
    
    @end
    

    注册自定义消息

    在实现了上面的自定义消息类后,您需要在 SDK 初始化之后,注册该自定义消息类。只有注册了该消息类型之后,SDK才能识别和编码、解码该类型的消息。

    // RCIMClient Class
    
    /*!
     注册自定义的消息类型
    
     @param messageClass    自定义消息的类,该自定义消息需要继承于RCMessageContent
    
     @discussion 如果您需要自定义消息,必须调用此方法注册该自定义消息的消息类型,否则SDK将无法识别和解析该类型消息。
    
     @warning 如果您使用IMLib,请使用此方法注册自定义的消息类型;
     如果您使用IMKit,请使用RCIM中的同名方法注册自定义的消息类型,而不要使用此方法。
     */
    - (void)registerMessageType:(Class)messageClass;
    

    用户信息显示

    融云 IM 不管理 App 的用户体系和好友关系,只要有一个合法的 UserId 就可以收发消息。

    当界面上需要显示用户信息(名字、头像)的时候,App 需要根据 userId 在自己的用户体系中查到对应的用户信息并显示。

    SDK 中针对聊天室的 IM 场景,在消息内容中设计了 senderUserInfo 字段。

    App 可以在发送消息的时候,携带发送者自己的用户信息(名字、头像),接收方在收到消息的时候可以根据此字段的信息进行 UI 展示。

        // RCMessageContent Class
    
        /*!
         消息内容中携带的发送者的用户信息
    
         @discussion
         如果您使用 IMKit,可以通过 RCIM 的 enableMessageAttachUserInfo 属性设置在每次发送消息中携带发送者的用户信息。
         */
        @property(nonatomic, strong) RCUserInfo *senderUserInfo;
    

    我们建议,如果您 App 只使用聊天室功能,则可以通过 senderUserInfo 传递并显示用户信息。

    如果您以后需要集成 IMKit 来扩展更多功能,则还需要实现用户信息提供者和群组信息提供者等协议,更多内容可以参考 iOS IMKit 开发指南

    连接状态监听

    您可以设置监听连接状态。

    // RCIMClient Class
    
    /*!
     设置IMLib的连接状态监听器
    
     @param delegate    IMLib连接状态监听器
    
     @warning 如果您使用IMLib,可以设置并实现此Delegate监听消息接收;
     如果您使用IMKit,请使用RCIM中的connectionStatusDelegate监听连接状态变化,而不要使用此方法,否则会导致IMKit中无法自动更新UI!
     */
    - (void)setRCConnectionStatusChangeDelegate: (id<RCConnectionStatusChangeDelegate>)delegate;
    

    您也可以直接获取当前的聊天状态。

    // RCIMClient Class
    
    /*!
     获取当前SDK的连接状态
    
     @return 当前SDK的连接状态
     */
    - (RCConnectionStatus)getConnectionStatus;
    

    断开连接

    在断开与融云服务器的连接的时候,您可以设置是否该客户端是否接收远程推送。 如果设置了接收推送,断开连接之后,如果有人给该用户 ID 发送消息,融云的服务器会根据 deviceToken 和推送证书将消息发送到苹果推送服务器,苹果服务器会将该消息以远程推送的形式下发到客户端。

    我们针对断开连接之后是否接收远程推送,提供了以下三个接口,您按照您的需求,调用其中一个即可。

    // RCIMClient Class
    
    /*!
     断开与融云服务器的连接
    
     @param isReceivePush   App在断开连接之后,是否还接收远程推送
    
     @discussion 因为SDK在前后台切换或者网络出现异常都会自动重连,会保证连接的可靠性。
     所以除非您的App逻辑需要登出,否则一般不需要调用此方法进行手动断开。
    
     @warning 如果您使用IMLib,请使用此方法断开与融云服务器的连接;
     如果您使用IMKit,请使用RCIM中的同名方法断开与融云服务器的连接,而不要使用此方法。
    
     isReceivePush指断开与融云服务器的连接之后,是否还接收远程推送。
     [[RCIMClient sharedRCIMClient] disconnect:YES]与[[RCIMClient sharedRCIMClient] disconnect]完全一致;
     [[RCIMClient sharedRCIMClient] disconnect:NO]与[[RCIMClient sharedRCIMClient] logout]完全一致。
     您只需要按照您的需求,使用disconnect:与disconnect以及logout三个接口其中一个即可。
     */
    - (void)disconnect:(BOOL)isReceivePush;
    
    /*!
     断开与融云服务器的连接,但仍然接收远程推送
    
     @discussion 因为SDK在前后台切换或者网络出现异常都会自动重连,会保证连接的可靠性。
     所以除非您的App逻辑需要登出,否则一般不需要调用此方法进行手动断开。
    
     @warning 如果您使用IMLib,请使用此方法断开与融云服务器的连接;
     如果您使用IMKit,请使用RCIM中的同名方法断开与融云服务器的连接,而不要使用此方法。
    
     [[RCIMClient sharedRCIMClient] disconnect:YES]与[[RCIMClient sharedRCIMClient] disconnect]完全一致;
     [[RCIMClient sharedRCIMClient] disconnect:NO]与[[RCIMClient sharedRCIMClient] logout]完全一致。
     您只需要按照您的需求,使用disconnect:与disconnect以及logout三个接口其中一个即可。
     */
    - (void)disconnect;
    
    /*!
     断开与融云服务器的连接,并不再接收远程推送
    
     @discussion 因为SDK在前后台切换或者网络出现异常都会自动重连,会保证连接的可靠性。
     所以除非您的App逻辑需要登出,否则一般不需要调用此方法进行手动断开。
    
     @warning 如果您使用IMKit,请使用此方法断开与融云服务器的连接;
     如果您使用IMLib,请使用RCIMClient中的同名方法断开与融云服务器的连接,而不要使用此方法。
    
     [[RCIMClient sharedRCIMClient] disconnect:YES]与[[RCIMClient sharedRCIMClient] disconnect]完全一致;
     [[RCIMClient sharedRCIMClient] disconnect:NO]与[[RCIMClient sharedRCIMClient] logout]完全一致。
     您只需要按照您的需求,使用disconnect:与disconnect以及logout三个接口其中一个即可。
     */
    - (void)logout;
    

    RCIMClient 接口说明

    RCIMClient 类是 IMLib 的核心类,您可以通过查看 API 文档了解更多接口的详情。