企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
会话和消息 SDK 中用户与同一个对象的聊天信息的集合,称为一个会话,用 `QDSession` 来表示。会话又单人会话,群组会话,应用会话,自定义会话等。 ``` typedef NS_ENUM(NSInteger, QDSessionType) { QDSessionTypeP2P = 0, /** 单聊会话*/ QDSessionTypeGroup = 1, /** 群组会话*/ QDSessionTypeMuser = 2, /** 群发会话*/ QDSessionTypeApp = 3, /** 应用会话*/ QDSessionTypeNotify = 4 /** 系统通知*/ }; @interface QDSession : NSObject /** 会话ID,如果当前session为group,则sessionId为groupId,如果是P2P则为对方帐号 */ @property (nonatomic, copy, readonly) NSString *sessionId; /** 会话类型 */ @property (nonatomic, assign, readonly) QDSessionType sessionType; /** 会话的扩展类型 (PC 端使用 暂时移动端没有使用) */ @property (nonatomic, copy, readonly, nullable) NSString *sessionExtType; /** 通过id、type和extType构造会话对象 @param sessionId 会话ID @param sessionType 会话类型 @param sessionExtType 会话扩展类型 @return 会话对象实例 */ + (instancetype)session:(NSString *)sessionId type:(QDSessionType)sessionType extType:(NSString * _Nullable )sessionExtType; @end ``` 在使用的时候,不需要去 SDK 获取会话对象,直接根据已有的会话 Id 和 类型构造出即可。 实例: ``` // p2p QDSession *friendSession = [QDSession session:@"friend user id" type:QDSessionTypeP2P extType:nil]; // group QDSession *groupSession = [QDSession session:group.ID type:QDSessionTypeGroup extType:nil]; ``` SDK 中用于表示消息结构为 `QDMessage` 。消息属于即时通讯中最关键最重要的类,它是传递信息的基本模型。 ``` /** 消息基础数据 */ @interface QDMessage : NSObject /** 消息ID,唯一标识 */ @property (nonatomic, copy) NSString *messageId; /** 消息类型 */ @property (nonatomic, assign) QDMessageType messageType; /** 所属会话 */ @property (nonatomic, strong) QDSession *session; /** 消息发送状态 */ @property (nonatomic, assign) QDMessageStatus status; /** 消息发送者id */ @property (nonatomic, copy) NSString *senderId; /** 消息发送者名字 */ @property (nonatomic, copy) NSString *senderName; /** senderssid */ @property (nonatomic, copy) NSString *ssid; /** 消息标题 */ @property (nonatomic, copy) NSString *title; /** 消息内容类型(text/json 等) */ @property (nonatomic, copy) NSString *contentType; /** 消息内容 */ @property (nonatomic, strong) NSString *content; /** 消息附件内容 */ @property (nullable, nonatomic, strong) id<QDMessageObject> messageObject; /** 额外消息数据 */ @property (nullable, nonatomic, copy) NSString *extData; /** 消息扩展类型 */ @property (nullable, nonatomic, copy) NSString *msgExtType; /** 消息信息标示 */ @property (nonatomic, assign) NSInteger msgFlag; /** 消息发送时间(纳秒级) @discussion 本地存储消息可以通过修改时间戳来调整其在会话列表中的位置,发完服务器的消息时间戳将被服务器自动修正 */ @property (nonatomic, assign) NSTimeInterval timestamp; /** 消息投递状态 仅针对发送的消息 */ @property (nonatomic, assign, readonly) QDMessageDeliveryState deliveryState; /** 是否是往外发的消息 */ @property (nonatomic, assign) BOOL isOutgoingMsg; /** 是否是收到的消息 @discussion 由于有漫游消息的概念,所以自己发出的消息漫游下来后仍旧是"收到的消息",这个字段用于消息出错是时判断需要重发还是重收 */ @property (nonatomic, assign, readonly) BOOL isReceivedMsg; /** 消息是否被播放过 */ @property (nonatomic, assign) BOOL isPlayed; /** 消息是否标记为已删除 @discussion 已删除的消息在获取本地消息列表时会被过滤掉,只有根据 messageId 获取消息的接口可能会返回已删除消息 */ @property (nonatomic, assign, readonly) BOOL isDeleted; /** 对端是否已读 @discussion 只有当当前消息为 P2P 消息且 isOutgoingMsg 为 YES 时这个字段才有效,需要对端调用过发送已读回执的接口 */ @property (nonatomic, assign, readonly) BOOL isRemoteRead; /** 是否本地已读 @discussion 标记未读消息使用 */ @property (nonatomic, assign, readonly) BOOL isLocalRead; /** 消息附件下载状态 仅针对收到的消息 */ @property (nonatomic, assign, readonly) QDMessageAttachmentDownloadState attachmentDownloadState; /** 附件信息 */ @property (nullable, nonatomic, copy) NSString *attachments; /** 消息打开时间 */ @property (nonatomic, assign) NSTimeInterval openTimestamp; /** 消息指令包body内容 (NSString、NSDictionary ...) */ @property (nonatomic, copy) id body; /** 消息来源类型 应用类消息对应的应用类型 */ @property (nonatomic, copy) NSString *appcode; /** 会话Id(服务端使用) */ @property (nonatomic, copy) NSString *conversationId; /** 消息序号 */ @property (nonatomic, assign) unsigned long long msgnum; /** 发送者的消息序号 */ @property (nonatomic, assign) unsigned long long senderMsgnum; /** * 模糊查询的消息数量 */ @property(nonatomic, assign) NSInteger msgCount; @end ``` 目前提供如下几种消息类型 ``` /** 消息内容类型枚举 */ typedef NS_ENUM(NSInteger, QDMessageType) { QDMessageTypeText = 0, /** 文本消息*/ QDMessageTypeRTF = 1, /** 富文本消息*/ QDMessageTypeImage = 2, /** 图片消息*/ QDMessageTypeFile = 3, /** 文件消息*/ QDMessageTypeAudio = 4, /** 语音消息*/ QDMessageTypeVideo = 5, /** 小视频*/ QDMessageTypeLocation = 6, /** 定位消息*/ QDMessageTypeLink = 7, /** 链接消息*/ QDMessageTypeConfirm = 8, /** 签收消息*/ QDMessageTypeConfirmed = 9, /** 确认签收消息*/ QDMessageTypeNotify = 10, /** 通知消息*/ QDMessageTypeRevoke = 11, /** 撤回消息*/ QDMessageTypeNetCallAudio = 12, /** 音频通话*/ QDMessageTypeNetCallVideo = 13, /** 视频通话*/ QDMessageTypeCustom = 14, /** 自定义消息*/ QDMessageTypeUnkonw = 15 /** 未知*/ }; ``` ### 消息发送 ``` @interface QDIM : NSObject /** 发送消息 @param message 消息 @param session 接受方 @param error 错误 如果在准备发送消息阶段发生错误,这个error会被填充相应的信息 @return 是否调用成功,这里返回的 result 只是表示当前这个函数调用是否成功,需要后续的回调才能够判断消息是否已经发送至服务器 */ - (BOOL)sendMessage:(QDMessage *)message toSession:(QDSession *)session error:(NSError * __nullable *)error; @end ``` 1. 文本消息 已发送一条文本消息 `hello word` 至好友 id 为 `userId` 的业务场景进行实例: ``` // 构造出具体会话 QDSession *session = [QDSession session:@"userId" type:QDSessionTypeP2P extType:nil]; // 构造出具体消息 QDMessage *msg = [QDMessageMaker msgWithText:@"hello word"]; // 错误反馈对象 NSError *error = nil; // 发送消息 [[QDIM sharedSDK] sendMessage:msg toSession:session error:&error ]; ``` 2. 图片消息 ``` // 构造出具体会话 QDSession *session = [QDSession session:@"userId" type:QDSessionTypeP2P extType:nil]; // 构造出具体消息 QDMessage *msg = [QDMessageMaker msgWithImage:image]; // 错误反馈对象 NSError *error = nil; // 发送消息 [[QDIM sharedSDK] sendMessage:msg toSession:session error:&error ]; ``` 3. 文件消息 ``` // 构造出具体会话 QDSession *session = [QDSession session:@"userId" type:QDSessionTypeP2P extType:nil]; // 构造出具体消息 QDMessage *msg = [QDMessageMaker msgWithFilePath:filePath]; // 错误反馈对象 NSError *error = nil; // 发送消息 [[QDIM sharedSDK] sendMessage:msg toSession:session error:&error ]; ``` 4. 其它消息 都可以通过 ` QDMessageMaker ` 创建消息 ``` @interface QDMessageMaker : NSObject + (QDMessage *)msgWithText:(NSString *)text; + (QDMessage *)msgWithFilePath:(NSString *)path; + (QDMessage *)msgWithFileData:(NSData *)data extension:(NSString *)extension; + (QDMessage *)msgWithImage:(UIImage *)image; + (QDMessage *)msgWithImagePath:(NSString *)path; + (QDMessage *)msgWithAudioPath:(NSString *)path; + (QDMessage *)msgWithVideoPath:(NSString *)path; + (QDMessage *)msgWithLatitude:(double)latitude longitude:(double)longitude title:(nullable NSString *)title info:(nullable NSString *)info; + (QDMessage *)msgWithForwardMessage:(QDMessage *)forwardMessage; + (QDMessage *)msgWithCollectMessage:(QDCollect *)collect; + (QDMessage *)msgWithText:(NSString *)text atHandler:(QDAtHandler *)atHandler; + (QDMessage *)confirmMsgWithText:(NSString *)text; @end ``` 发送消息的进度,结果可以通过协议监听 ``` @protocol QDChatManagerDelegate <NSObject> @optional /** 即将发送消息回调 @discussion 因为发消息之前可能会有个异步的准备过程,所以需要在收到这个回调时才将消息加入到datasource中 @param message 当前发送的消息 */ - (void)willSendMessage:(QDMessage *)message; /** 发送消息进度回调 @param message 当前发送的消息 @param progress 进度 */ - (void)sendMessage:(QDMessage *)message progress:(float)progress; /** 发送消息完成回调 @param message 当前发送的消息 @param error 失败原因,如果发送成功则error为nil */ - (void)sendMessage:(QDMessage *)message didCompleteWithError:(nullable NSError *)error; ``` ### 接收消息 ``` @protocol QDChatManagerDelegate <NSObject> ** 收到消息回调 @param messages 消息列表,内部为QDMessage */ - (void)onRecvMessages:(NSArray<QDMessage *> *)messages; /** 收到消息回执 */ - (void)onRecvReceiptsMessage:(QDMessage *)message; /** 收取消息附件回调 @param message 当前收取的消息 @param progress 进度 @discussion 附件包括:图片,视频的缩略图,语音文件 */ - (void)fetchMessageAttachment:(QDMessage *)message progress:(float)progress; /** 收取消息附件完成回调 @param message 当前收取的消息 @param error 错误返回,如果收取成功,error为nil */ - (void)fetchMessageAttachment:(QDMessage *)message didCompleteWithError:(nullable NSError *)error; /** 收到消息被撤回的通知 @param notification 被撤回的消息信息 @discusssion 收到消息撤回后,会先从本地数据库中找到对应消息并进行删除,之后通知上层消息已删除 */ - (void)onRecvRevokeMessageNotification:(QDRevokeMessageNotification *)notification; /** 收取确认签收消息的通知 @param notification 被签收的消息信息 */ - (void)onRecvConfirmedMessageNotification:(QDConfirmedMessageNotification *)notification; ``` ### 最近会话 最近会话有变化时可以通过监听 `QDConversationManagerDelegate` 协议来实现 ``` /** 添加会话委托 @param delegate 通知对象 */ - (void)addConversationDelegate:(id<QDConversationManagerDelegate>)delegate; /** 删除会话委托 @param delegate 通知对象 */ - (void)removeConversationDelegate:(id<QDConversationManagerDelegate>)delegate; /** 删除某个会话的所有消息 @param session 待删除会话 */ - (void)deleteAllmessagesInSession:(QDSession *)session; /** 设置一个会话里所有消息置为已读 @param session 需设置的会话 */ - (void)markAllMessagesReadInSession:(QDSession *)session; /** 删除某个最近会话 @param recentSession 待删除的最近会话 */ - (void)deleteRecentSession:(QDRecentSession *)recentSession; /** 更新最近会话的本地扩展 @param ext 扩展信息 @param session 要更新的会话 @discussion 此扩展不会漫游到其他端,上层需要保证 NSDictionary 可以转换为 JSON。 */ - (void)updateRecentLocalExt:(nullable NSDictionary *)ext session:(QDSession *)session; ```