协同sdk说明


消息

<p>[TOC]</p> <h2>会话和消息</h2> <p>SDK 中用户与同一个对象的聊天信息集合,称为一个会话,用 QDSession 来表示。会话有单人会话,群组会话等类型。 原型</p> <pre><code>typedef NS_ENUM(NSInteger, QDSessionType) { QDSessionTypeP2P = 0, /** 单聊会话*/ QDSessionTypeGroup = 1, /** 群组会话*/ QDSessionTypeChatroom = 2, /** 聊天室 暂时未启用*/ QDSessionTypeApp = 3, /** 应用消息 移动端不支持发送*/ QDSessionTypeMiLiao = 4, /** 密聊消息类型*/ }; @interface QDSession : NSObject&lt;NSCopying&gt; /** * 会话ID,如果当前session为group,则sessionId为groupId,如果是P2P则为对方帐号 */ @property (nonatomic, copy, readonly) NSString *sessionId; /** * 会话类型 */ @property (nonatomic, assign, readonly) QDSessionType sessionType; /** * 通过id、type和extType构造会话对象 * * @param sessionId 会话ID * @param sessionType 会话类型 * @return 会话对象实例 */ + (instancetype)session:(NSString *)sessionId type:(QDSessionType)sessionType; @end</code></pre> <p>在使用的时候,不需要去 SDK 获取会话对象,直接根据已有的会话 Id 和 类型构造出即可。</p> <p>示例</p> <pre><code>//p2p QDSession *myFriendSession = [QDSession session:@"friend user id" type:QDSessionTypeP2P]; //team QDSession *teamSession = [QDSession session:@"team id" type:QDSessionTypeGroup]; //do something with session</code></pre> <p>SDK 中用于表示消息的结构为 QDMessage。消息属于即时通讯中最关键最重要的类,它是传递信息的基本模型。</p> <p>原型</p> <pre><code>@interface QDMessage : NSObject /** * 消息ID,唯一标识 */ @property (nonatomic, copy ) NSString *messageId; /** * 引用消息的消息ID */ @property (nonatomic, copy ) NSString *sourcemsgId; /** * 消息类型 */ @property (nonatomic, assign) QDMessageType messageType; /** * 消息信息标示 2:强通知 4:签收消息 */ @property (nonatomic, assign) NSInteger msgFlag; /** * 所属会话 */ @property (nonatomic, strong) QDSession *session; /** * 消息发送者id */ @property (nonatomic, copy) NSString *senderId; /** * 消息发送者名字 */ @property (nonatomic, copy) NSString *senderName; /** * 消息发送者头像信息 */ @property (nonatomic, copy) NSString *senderAvatar; /** * 消息标题 */ @property (nonatomic, copy) NSString *title; /** * 消息文本 * @discussion 消息中除 QDMessageTypeText 外,其他消息 text 字段都为 nil 如果text文本长度超过 1000 则会截取到 1000 */ @property (nonatomic, strong) NSString *text; /** * 消息内容信息 */ @property (nonatomic, copy) NSString *content; /** * 消息附件内容 */ @property (nullable, nonatomic, strong) id&lt;QDMessageObject&gt; messageObject; /** * 附件信息 */ @property (nullable, nonatomic, copy) NSString *attachments; /** * 服务端扩展字段 */ @property (nonatomic, strong) id remoteExt; /** * 客户端本地扩展 */ @property (nonatomic, strong) NSDictionary *localExt; /** * 消息发送时间(纳秒级) * * @discussion 本地存储消息可以通过修改时间戳来调整其在会话列表中的位置,发完服务器的消息时间戳将被服务器自动修正 */ @property (nonatomic, assign) NSTimeInterval timestamp; /** * 消息是否被播放过 */ @property (nonatomic, assign) BOOL isPlayed; /** * 消息是否需要被计入未读计数 ** @discussion 默认为YES。默认情况下,用户收到的所有消息都会被计入未读。设置这个为NO后,对应的消息被对端接受后将不计入未读消息计数内。 */ @property (nonatomic, assign) BOOL shouldBeCounted; /** * 消息打开时间 */ @property (nonatomic, assign) NSTimeInterval openTimestamp; /** * 是否是往外发的消息 */ @property (nonatomic, assign, readonly) BOOL isOutgoingMsg; /** * 是否是收到的消息 * * @discussion 由于有漫游消息的概念,所以自己发出的消息漫游下来后仍旧是"收到的消息",这个字段用于消息出错是时判断需要重发还是重收 */ @property (nonatomic, assign, readonly) BOOL isReceivedMsg; /** * 消息是否标记为已删除 * * @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) QDPlatfromType senderClientType; /** * 消息发送状态 */ @property (nonatomic, assign, readonly) QDMessageStatus status; /** * 消息投递状态 仅针对发送的消息 */ @property (nonatomic, assign, readonly) QDMessageDeliveryState deliveryState; /** * 消息附件下载状态 仅针对收到的消息 */ @property (nonatomic, assign, readonly) QDMessageAttachmentDownloadState attachmentDownloadState; /** * 会话Id(服务端使用) */ @property (nonatomic, copy) NSString *conversationId; /** * 消息序号 */ @property (nonatomic, assign) unsigned long long msgnum; /** * 发送者的消息序号 */ @property (nonatomic, assign) unsigned long long senderMsgnum; @end</code></pre> <p>上述消息的状态属性,推荐只在主线程对这些属性进行读写</p> <p>目前提供如下几种消息类型,不同的消息类型对应不同的 MessageObject</p> <table> <thead> <tr> <th style="text-align: center;">消息格式</th> <th style="text-align: center;">MessageObject</th> </tr> </thead> <tbody> <tr> <td style="text-align: center;">文本消息</td> <td style="text-align: center;">nil</td> </tr> <tr> <td style="text-align: center;">图片消息</td> <td style="text-align: center;">QDImageObject</td> </tr> <tr> <td style="text-align: center;">音频消息</td> <td style="text-align: center;">QDAudioObject</td> </tr> <tr> <td style="text-align: center;">视频消息</td> <td style="text-align: center;">QDVideoObject</td> </tr> <tr> <td style="text-align: center;">文件消息</td> <td style="text-align: center;">QDFileObject</td> </tr> <tr> <td style="text-align: center;">地理位置消息</td> <td style="text-align: center;">QDLocationObject</td> </tr> <tr> <td style="text-align: center;">通知消息</td> <td style="text-align: center;">QDNotificationObject</td> </tr> <tr> <td style="text-align: center;">提醒消息</td> <td style="text-align: center;">QDTipObject</td> </tr> </tbody> </table> <h2>消息发送</h2> <p>开发者需要通过 QDClient 里的 QDIMChatManager 协议进行消息发送</p> <p>原型</p> <pre><code>@protocol QDIMChatManager &lt;NSObject&gt; /** * 发送消息 * * @param message 消息 (暂不支持提醒消息) * @param session 接受方 * @param error 错误 如果在准备发送消息阶段发生错误,这个error会被填充相应的信息 * @return 是否调用成功,这里返回的 result 只是表示当前这个函数调用是否成功,需要后续的回调才能够判断消息是否已经发送至服务器 */ - (BOOL)sendMessage:(QDMessage *)message toSession:(QDSession *)session error:(NSError * _Nullable *)error; @end</code></pre> <p>属性列表</p> <table> <thead> <tr> <th style="text-align: center;">参数</th> <th style="text-align: center;">类型</th> <th style="text-align: center;">说明</th> </tr> </thead> <tbody> <tr> <td style="text-align: center;">message</td> <td style="text-align: center;">QDMessage</td> <td style="text-align: center;">需要发送的消息,开发者构造出 message 后,需要选择构造对应的 messageObject (文本消息直接填入 text 即可,无须消息附件注入),即可传入此接口进行发送</td> </tr> <tr> <td style="text-align: center;">session</td> <td style="text-align: center;">QDSession</td> <td style="text-align: center;">需要发送到的会话</td> </tr> <tr> <td style="text-align: center;">error</td> <td style="text-align: center;">NSError</td> <td style="text-align: center;">开发者需要自己构造出一个 NSError 对象,并将对象引用传入。如果在准备发送消息阶段发生错误,这个对象会被填充相应的信息。通常为参数检查错误或者登录状态错误,可参考错误码说明定位具体的出错类型</td> </tr> </tbody> </table> <p>1 文本消息。</p> <p>以发送一条文本消息 <code>hello Qida</code> 至好友Id 为 <code>account</code> 的业务场景</p> <pre><code>// 构造出具体会话 QDSession *session = [QDSession session:@"account" type:QDSessionTypeP2P]; // 构造出具体消息 QDMessage *message = [[QDMessage alloc] init]; message.text = @"hello Qida"; // 错误反馈 NSError *error = nil; // 发送消息 [[QDClient sharedClient].chatManager sendMessage:message toSession:session error:&amp;error];</code></pre> <p>2 图片消息。</p> <p>附件原型:</p> <pre><code>@interface QDImageObject : NSObject &lt;QDMessageObject&gt; /** * 图片实例对象初始化方法 * * @param image 要发送的图片 * @return 图片选项 */ - (instancetype)initWithImage:(UIImage *)image; /** * 图片实例对象初始化方法 * * @param image 要发送的图片 * @param imageOption 图片选项 * @return 图片实例对象 */ - (instancetype)initWithImage:(UIImage *)image imageOption:(QDImageOption * _Nullable)imageOption; /** * 图片实例对象初始化方法 * * @param filepath 要发送的图片路径 * @return 图片实例对象 * @discussion 使用此方法上传是不做压缩转换的原图上传 */ - (instancetype)initWithSourcePath:(NSString *)filepath; /** * 展示名 */ @property (nullable, nonatomic, copy) NSString *fileName; /** * 图片guid */ @property (nullable, nonatomic, copy, readonly) NSString *guid; /** * 图片尺寸 */ @property (nonatomic, assign, readonly) CGSize size; /** * 图片本地路径 * @discussion 目前 SDK 没有提供下载大图的方法,但推荐使用这个地址作为图片下载地址 */ @property (nullable, nonatomic, copy, readonly) NSString *path; /** * 本地缩略图路径 */ @property (nullable, nonatomic, copy, readonly) NSString *thumbPath; /** * 图片远程路径 */ @property (nullable, nonatomic, copy, readonly) NSString *url; /** * 略缩图远程路径 */ @property (nullable, nonatomic, copy, readonly) NSString *thumbUrl; /** * 图片选项 * @discussion 仅在发送时且通过 initWithImage: 方式初始化才有效 */ @property (nullable, nonatomic ,strong) QDImageOption *option; /** * 文件大小 */ @property (nonatomic, assign, readonly) long long fileLength; /** * 图片MD5 */ @property (nullable,nonatomic, copy, readonly) NSString *md5; @end</code></pre> <p>参数列表</p> <table> <thead> <tr> <th style="text-align: center;">参数</th> <th style="text-align: center;">类型</th> <th style="text-align: center;">说明</th> </tr> </thead> <tbody> <tr> <td style="text-align: center;">path</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">图片本地路径,目前 SDK 没有提供下载大图的方法,但推荐使用这个地址作为图片下载地址, APP 可以使用自己的下载类或者 SDWebImage 做图片的下载和管理</td> </tr> <tr> <td style="text-align: center;">thumbPath</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">缩略图本地路径,缩略图在默认情况下由 SDK 自动下载,如果发现本地不存在缩略图,可手动调用 QDIMChatManager 协议中的获取缩略图方法 fetchMessageAttachment:error: 进行下载</td> </tr> <tr> <td style="text-align: center;">url</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">大图的远程 URL 路径,开发者可通过这个属性自行下载大图</td> </tr> <tr> <td style="text-align: center;">thumbUrl</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">缩略图远程 URL 路径,仅适用于使用SDK上传服务进行上传的资源,否则无效</td> </tr> <tr> <td style="text-align: center;">size</td> <td style="text-align: center;">CGSize</td> <td style="text-align: center;">图片尺寸</td> </tr> <tr> <td style="text-align: center;">option</td> <td style="text-align: center;">QDImageOption</td> <td style="text-align: center;">图片的压缩选项仅在发送时且通过 initWithImage: 方式初始化才有效</td> </tr> <tr> <td style="text-align: center;">fieLength</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">文件大小</td> </tr> <tr> <td style="text-align: center;">md5</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">图片MD5</td> </tr> </tbody> </table> <p>QDImageOption 图片选项参数列表</p> <table> <thead> <tr> <th style="text-align: center;">参数</th> <th style="text-align: center;">类型</th> <th style="text-align: center;">说明</th> </tr> </thead> <tbody> <tr> <td style="text-align: center;">compressQuality</td> <td style="text-align: center;">float</td> <td style="text-align: center;">压缩参数默认为 0.5 ,可传入 0.0 - 1.0 的值,如果值为 0 或者不合法参数时按照 0.5 进行压缩</td> </tr> <tr> <td style="text-align: center;">format</td> <td style="text-align: center;">QDImageFormat</td> <td style="text-align: center;">图片压缩格式,可选 JPEG 和 PNG 两种。默认为 JPEG</td> </tr> </tbody> </table> <p>以发送一条图片消息, 数据被 image 引用, 至好友 Id 为 user 的业务场景进行示例:</p> <pre><code>// 构造出具体会话 QDSession *session = [QDSession session:@"user" type:QDSessionTypeP2P]; // 获得图片附件对象 QDImageObject *object = [[QDImageObject alloc] initWithImage:image]; // 构造出具体消息并注入附件 QDMessage *message = [[QDMessage alloc] init]; message.messageObject = object; // 错误反馈对象 NSError *error = nil; // 发送消息 [[QDClient sharedClient].chatManager sendMessage:message toSession:session error:&amp;error];</code></pre> <p>以发送一条图片消息, 数据在路径 path 中, 至好友 Id 为 user 的业务场景进行示例:</p> <pre><code>// 构造出具体会话 QDSession *session = [QDSession session:@"user" type:QDSessionTypeP2P]; // 获得图片附件对象 QDImageObject *object = [[QDImageObject alloc] initWithSourcePath:path]; // 构造出具体消息并注入附件 QDMessage *message = [[QDMessage alloc] init]; message.messageObject = object; // 错误反馈对象 NSError *error = nil; // 发送消息 [[QDClient sharedClient].chatManager sendMessage:message toSession:session error:&amp;error];</code></pre> <p>3 音频消息</p> <p>附件原型:</p> <pre><code>@interface QDAudioObject : NSObject &lt;QDMessageObject&gt; /** * 文件展示名 */ @property (nullable, nonatomic, copy) NSString *fileName; /** * 声音文件的 guid */ @property (nullable, nonatomic, copy, readonly) NSString *guid; /** * 语音的本地路径 */ @property (nullable, nonatomic, copy, readonly) NSString *path; /** * 语音的远程路径 */ @property (nullable, nonatomic, copy, readonly) NSString *url; /** * 文件大小 */ @property (nonatomic, assign, readonly) long long fileLength; /** * 语音时长,毫秒为单位 */ @property (nonatomic, assign) long long duration; /** * 语音对象初始化方法 * * @param sourcePath 语音路径 * @return 语音实例对象 */ - (instancetype)initWithSourcePath:(NSString *)sourcePath; @end</code></pre> <p>参数列表</p> <table> <thead> <tr> <th style="text-align: center;">参数</th> <th style="text-align: center;">类型</th> <th style="text-align: center;">说明</th> </tr> </thead> <tbody> <tr> <td style="text-align: center;">fileName</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">文件展示名</td> </tr> <tr> <td style="text-align: center;">guid</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">文件在服务端的存储id</td> </tr> <tr> <td style="text-align: center;">path</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">语音本地路径,语音在默认情况下由 SDK 自动下载,如果发现本地不存在语音文件,可手动调用 QDIMChatManager 协议中的获取语音附件方法 fetchMessageAttachment:error: 进行下载</td> </tr> <tr> <td style="text-align: center;">url</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">语音的远程 URL 路径</td> </tr> <tr> <td style="text-align: center;">duration</td> <td style="text-align: center;">long long</td> <td style="text-align: center;">语音时长,毫秒为单位</td> </tr> <tr> <td style="text-align: center;">fileLength</td> <td style="text-align: center;">long long</td> <td style="text-align: center;">语音文件大小</td> </tr> </tbody> </table> <p>提供一种初始化</p> <pre><code>/** * 语音对象初始化方法 * * @param sourcePath 语音路径 * @return 语音实例对象 */ - (instancetype)initWithSourcePath:(NSString *)sourcePath;</code></pre> <p>以发送一条语音消息, 语音保存在路径 path 中, 至好友 Id 为 user 的业务场景进行示例:</p> <pre><code>// 构造出具体会话 QDSession *session = [QDSession session:@"user" type:QDSessionTypeP2P]; // 获得语音附件对象 QDAudioObject *object = [[QDAudioObject alloc] initWithSourcePath:path]; // 构造出具体消息并注入附件 QDMessage *message = [[QDMessage alloc] init]; message.messageObject = object; // 错误反馈对象 NSError *error = nil; // 发送消息 [[QDClient sharedClient].chatManager sendMessage:message toSession:session error:&amp;error];</code></pre> <p>4 视频消息</p> <p>附件原型:</p> <pre><code>@interface QDVideoObject : NSObject &lt;QDMessageObject&gt; /** * 小视频实例对象初始化方法 * * @param filepath 要发送的视频路径 * @return 小视频实例对象 */ - (instancetype )initWithSourcePath:(NSString *)filepath; /** * 文件展示名 */ @property (nullable, nonatomic, copy) NSString *fileName; /** * 小视频的guid */ @property (nullable, nonatomic, copy, readonly) NSString *guid; /** * 视频MD5 */ @property (nullable, nonatomic, copy, readonly) NSString *md5; /** * 本地路径 */ @property (nullable, nonatomic, copy, readonly) NSString *path; /** * 远程路径 */ @property (nullable, nonatomic, copy, readonly) NSString *url; /** * 视频封面的远程路径 */ @property (nullable, nonatomic, copy, readonly) NSString *coverUrl; /** * 视频封面的本地路径 */ @property (nullable, nonatomic, copy, readonly) NSString *coverPath; /** * 封面尺寸 */ @property (nonatomic, assign, readonly) CGSize coverSize; /** * 文件大小 */ @property (nonatomic, assign, readonly) long long fileLength; @end</code></pre> <p>参数列表</p> <table> <thead> <tr> <th style="text-align: center;">参数</th> <th style="text-align: center;">类型</th> <th style="text-align: center;">说明</th> </tr> </thead> <tbody> <tr> <td style="text-align: center;">fileName</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">文件展示名</td> </tr> <tr> <td style="text-align: center;">guid</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">文件在服务端的存储id</td> </tr> <tr> <td style="text-align: center;">path</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">视频的本地路径。目前 SDK 并不提供视频下载功能,但是建议 APP 使用这个 path 作为视频的下载地址,以便后期 SDK 提供缓存清理等功能</td> </tr> <tr> <td style="text-align: center;">url</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">视频的远程路径</td> </tr> <tr> <td style="text-align: center;">fileLength</td> <td style="text-align: center;">long long</td> <td style="text-align: center;">视频文件大小</td> </tr> <tr> <td style="text-align: center;">md5</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">根据视频生成的MD5</td> </tr> <tr> <td style="text-align: center;">coverUrl</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">视频封面的远程路径</td> </tr> <tr> <td style="text-align: center;">coverPath</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">视频封面的本地路径。视频封面在默认情况下由 SDK 自动下载,如果发现本地不存在封面文件,可手动调用 QDChatManager 协议中的获取封面方法 fetchMessageAttachment:error: 进行下载</td> </tr> <tr> <td style="text-align: center;">coverSize</td> <td style="text-align: center;">CGSize</td> <td style="text-align: center;">视频封面的大小,由 SDK 自行计算</td> </tr> </tbody> </table> <p>以路径初始化<br /> 原型</p> <pre><code>@interface QDVideoObject : NSObject &lt;QDMessageObject&gt; /** * 小视频实例对象初始化方法 * * @param filepath 要发送的视频路径 * @return 小视频实例对象 */ - (instancetype )initWithSourcePath:(NSString *)filepath; @end</code></pre> <p>以发送一条视频消息, 视频保存在路径 path 中, 至好友 Id 为 user 的业务场景进行示例:</p> <pre><code>// 构造出具体会话 QDSession *session = [QDSession session:@"user" type:QDSessionTypeP2P]; // 获得视频附件对象 QDVideoObject *object = [[QDVideoObject alloc] initWithSourcePath:path]; // 构造出具体消息并注入附件 QDMessage *message = [[QDMessage alloc] init]; message.messageObject = object; // 错误反馈对象 NSError *error = nil; // 发送消息 [[QDClient sharedClient].chatManager sendMessage:message toSession:session error:&amp;error];</code></pre> <p>5 文件消息<br /> 附件原型:</p> <pre><code>/** * 文件实例对象 */ @interface QDFileObject : NSObject &lt;QDMessageObject&gt; /** * 文件对象初始化方法(根据文件路径) * * @param sourcePath 文件路径 * @return 文件实例对象 */ - (instancetype)initWithSourcePath:(NSString *)sourcePath; /** * 文件对象初始化方法(根据文件数据) * * @param data 文件数据 * @param extension 文件拓展名 * @return 文件实例对象 */ - (instancetype)initWithData:(NSData *)data extension:(NSString *)extension; /** * 文件显示名 */ @property (nullable, nonatomic, copy) NSString *fileName; /** * 文件Id */ @property (nullable, nonatomic, copy, readonly) NSString *guid; /** * 文件的本地路径 */ @property (nullable, nonatomic, copy, readonly) NSString *path; /** * 文件的远程路径 */ @property (nullable, nonatomic, copy, readonly) NSString *url; /** * 文件MD5 */ @property (nullable, nonatomic, copy, readonly) NSString *md5; /** * 文件大小 */ @property (nonatomic, assign, readonly) long long fileLength; @end</code></pre> <p>参数列表</p> <table> <thead> <tr> <th style="text-align: center;">参数</th> <th style="text-align: center;">类型</th> <th style="text-align: center;">说明</th> </tr> </thead> <tbody> <tr> <td style="text-align: center;">fileName</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">文件展示名</td> </tr> <tr> <td style="text-align: center;">guid</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">文件在服务端的存储id</td> </tr> <tr> <td style="text-align: center;">path</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">文件的本地路径</td> </tr> <tr> <td style="text-align: center;">url</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">文件的远程路径</td> </tr> <tr> <td style="text-align: center;">fileLength</td> <td style="text-align: center;">long long</td> <td style="text-align: center;">文件大小</td> </tr> <tr> <td style="text-align: center;">md5</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">根据文件生成的MD5</td> </tr> </tbody> </table> <p>文件消息附件初始化提供两种方式:</p> <p>以发送一条文件消息, 文件保存在路径 path 中, 至好友 Id 为 user 的业务场景进行示例:</p> <pre><code>// 构造出具体会话 QDSession *session = [QDSession session:@"user" type:QDSessionTypeP2P]; // 获得文件附件对象 QDFileObject *object = [[QDFileObject alloc] initWithSourcePath:path]; // 构造出具体消息并注入附件 QDMessage *message = [[QDMessage alloc] init]; message.messageObject = object; // 错误反馈对象 NSError *error = nil; // 发送消息 [[QDClient sharedClient].chatManager sendMessage:message toSession:session error:&amp;error];</code></pre> <p>以发送一条文件消息, 文件数据被 data 引用, 至好友 Id 为 user 的业务场景进行示例:</p> <pre><code>// 构造出具体会话 QDSession *session = [QDSession session:@"user" type:QDSessionTypeP2P]; // 获得文件附件对象 QDFileObject *object = [[QDFileObject alloc] initWithData:data extension:@"data"]; // 构造出具体消息并注入附件 QDMessage *message = [[QDMessage alloc] init]; message.messageObject = object; // 错误反馈对象 NSError *error = nil; // 发送消息 [[QDClient sharedClient].chatManager sendMessage:message toSession:session error:&amp;error];</code></pre> <p>6 位置消息<br /> 附件原型:</p> <pre><code>@interface QDLocationObject : NSObject &lt;QDMessageObject&gt; /** 纬度 */ @property (nonatomic, assign, readonly) double latitude; /** 经度 */ @property (nonatomic, assign, readonly) double longitude; /** 标题 */ @property (nullable, nonatomic, copy, readonly) NSString *title; /** 地理位置描述 */ @property (nullable, nonatomic, copy, readonly) NSString *info; /** 位置实例对象初始化方法 @param latitude 纬度 @param longitude 经度 @param title 标题 @param info 地理位置描述 @return 位置实例对象 */ - (instancetype)initWithLatitude:(double)latitude longitude:(double)longitude title:(nullable NSString *)title info:(nullable NSString *)info; @end</code></pre> <p>参数列表</p> <table> <thead> <tr> <th style="text-align: center;">参数</th> <th style="text-align: center;">类型</th> <th style="text-align: center;">说明</th> </tr> </thead> <tbody> <tr> <td style="text-align: center;">latitude</td> <td style="text-align: center;">double</td> <td style="text-align: center;">维度位置,由初始化时传入</td> </tr> <tr> <td style="text-align: center;">longitude</td> <td style="text-align: center;">double</td> <td style="text-align: center;">维度位置,由初始化时传入</td> </tr> <tr> <td style="text-align: center;">title</td> <td style="text-align: center;">NSString</td> <td style="text-align: center;">位置标题信息,由初始化时传入</td> </tr> <tr> <td style="text-align: center;">info</td> <td style="text-align: center;">long long</td> <td style="text-align: center;">位置详情信息,由初始化时传入</td> </tr> </tbody> </table> <p>以发送一条位置消息, 经纬度为 (48.28476,120.94720) ,地点名为 address , 至好友 Id 为 user 的业务场景进行示例:</p> <pre><code>// 构造出具体会话 QDSession *session = [QDSession session:@"user" type:QDSessionTypeP2P]; // 获得位置附件对象 QDLocationObject *object = [[QDLocationObject alloc] initWithLatitude:120.94720 longitude:48.28476 title:@"title" info:@"address"]; // 构造出具体消息并注入附件 QDMessage *message = [[QDMessage alloc] init]; message.messageObject = object; // 错误反馈对象 NSError *error = nil; // 发送消息 [[QDClient sharedClient].chatManager sendMessage:message toSession:session error:&amp;error];</code></pre> <p>7 通知消息</p> <p>一些特定场景的行为,服务器预置了一些通知消息。通知消息也是一种特定消息,开发者需要解析消息中附带的信息,来获取通知内容。</p> <p>附件原型:</p> <pre><code>@interface QDNotificationObject : NSObject &lt;QDMessageObject&gt; /** * 通知内容 */ @property (nonatomic, strong, readonly) QDNotificationContent *content; /** * 通知类型 */ @property (nonatomic, assign, readonly) QDNotificationType notificationType; @end</code></pre> <table> <thead> <tr> <th style="text-align: center;">参数列表</th> <th style="text-align: center;">参数</th> <th style="text-align: center;">类型</th> <th>说明</th> </tr> </thead> <tbody> <tr> <td style="text-align: center;">content</td> <td style="text-align: center;">QDNotificationContent</td> <td style="text-align: center;">通知内容</td> </tr> <tr> <td style="text-align: center;">notificationType</td> <td style="text-align: center;">QDNotificationType</td> <td style="text-align: center;">通知类型,通知类型会随着 SDK 版本升级扩展,开发者需要考虑升级所带来的兼容问题</td> </tr> </tbody> </table> <h2>接收消息</h2> <p>接收消息过程通过 chatManager 的回调函数通知上层</p> <p>原型</p> <pre><code>@protocol QDChatManagerDelegate &lt;NSObject&gt; /** * 收到消息回调 * * @param messages 消息列表,内部为QDMessage */ - (void)onRecvMessages:(NSArray&lt;QDMessage *&gt; *)messages; @end</code></pre> <p>参数列表</p> <table> <thead> <tr> <th style="text-align: center;">参数</th> <th style="text-align: center;">类型</th> <th style="text-align: center;">说明</th> </tr> </thead> <tbody> <tr> <td style="text-align: center;">messages</td> <td style="text-align: center;">NSArray</td> <td style="text-align: center;">消息集合,集合按时间排序并保证所属同一个会话</td> </tr> </tbody> </table> <p>如果收到的是图片,视频等需要下载附件的消息,在回调的处理中还需要调用下载附件接口</p> <p>原型</p> <pre><code>@protocol QDIMChatManager &lt;NSObject&gt; /** * 收取消息附件 * * @param message 需要收取附件的消息 * @param error 错误 * @return 是否调用成功 * @discussion 附件包括:图片消息的图片缩略图,视频消息的视频缩略图,音频消息的音频文件,文件消息的文件以及自定义消息中的自定义文件 * 个人和群组消息 SDK 会在收到该消息时自动调用本接口,自动下载除 "文件消息的文件" 外的所有附件内容 */ - (BOOL)fetchMessageAttachment:(QDMessage *)message error:(NSError * __nullable *)error; @end</code></pre> <p>进行附件的下载,附件的下载过程会通过回调反馈</p> <pre><code>@protocol QDChatManagerDelegate &lt;NSObject&gt; /** * 收取消息附件回调 * * @param message 当前收取的消息 * @param progress 进度 (0-1) * @discussion 附件包括:图片,视频的缩略图,语音文件 */ - (void)fetchMessageAttachment:(QDMessage *)message progress:(float)progress; @end</code></pre> <h2>已读回执</h2> <p>在会话界面中调用发送已读回执的接口并传入最后一条消息,即表示这之前的消息都已读,对端将收到此回执。</p> <p>发送已读回执</p> <pre><code>@protocol QDChatManager &lt;NSObject&gt; /** * 发送已读消息 * * @param message 已读消息 * @param completion 完成回调 */ - (void)sendMessageReceipt:(QDMessage *)message completion:(void(^ _Nullable)(NSError * _Nullable error))completion; @end</code></pre> <p>接收已读回执</p> <pre><code>@protocol QDChatManagerDelegate &lt;NSObject&gt; /** * 收到消息回执 */ - (void)onRecvReceiptsMessage:(QDMessage *)message; @end</code></pre> <p>消息撤回</p> <p>在会话时,允许用户撤回一定时间内发送过的消息。</p> <pre><code>@protocol QDIMChatManager &lt;NSObject&gt; /** * 撤回消息 * * @param message 需要被撤回的消息 * @param completion 完成回调 */ - (void)revokeMessage:(QDMessage *)message completion:(void(^ _Nullable)(NSError * _Nullable error))completion;</code></pre> <p>在撤回消息请求调用成功后, SDK 会先回调给上层成功,再自动将本地的这条消息删除。如果需要在撤回后显示一条已撤回的提示 ( 见 Demo 交互 ) ,开发者可以自行构造一条提醒消息并插入本地数据库。</p> <p>当有消息撤回发生时,被撤回方 SDK 会触发回调:</p> <pre><code>@protocol QDChatManagerDelegate &lt;NSObject&gt; /** * 收到消息被撤回的通知 * * @param notification 被撤回的消息信息 * @discusssion 云信在收到消息撤回后,会先从本地数据库中找到对应消息并进行删除,之后通知上层消息已删除 */ - (void)onRecvRevokeMessageNotification:(QDRevokeMessageNotification *)notification; @end</code></pre> <p>SDK 在收到消息撤回后,会先从本地数据库中找到对应消息并进行删除,之后通知上层消息已删除。如果需要在撤回后显示一条已撤回的提示 ( 见 Demo 交互 ) ,开发者在这个回调中自行构造一条提醒消息并插入本地数据库。</p>

页面列表

ITEM_HTML