差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 上一修订版 两侧同时换到之后的修订记录 | ||
im:ios:basics:message [2020/06/25 02:41] jliu |
im:ios:basics:message [2022/02/28 07:39] jennifer.zeng |
||
---|---|---|---|
行 1: | 行 1: | ||
====== 消息 ====== | ====== 消息 ====== | ||
- | 消息:IM 交互实体,在 SDK 中对应的类型是 **EMMessage**。**EMMessage** 由 EMMessageBody 组成。 | + | 更新时间:2022-2-15 |
+ | |||
+ | 新版文档见:[[ccim:ios:message1|消息管理]]。 | ||
+ | |||
+ | ----- | ||
+ | |||
+ | 消息:IM 交互实体,在 SDK 中对应的类型是 **EMChatMessage**。**EMChatMessage** 由 EMMessageBody 组成。 | ||
消息涉及到的环信SDK头文件如下: | 消息涉及到的环信SDK头文件如下: | ||
<code objc> | <code objc> | ||
// 消息构建部分 | // 消息构建部分 | ||
- | EMMessage.h | + | EMChatMessage.h |
EMMessageBody.h | EMMessageBody.h | ||
EMTextMessageBody.h | EMTextMessageBody.h | ||
行 155: | 行 161: | ||
//message.chatType = EMChatTypeGroupChat;// 设置为群聊消息 | //message.chatType = EMChatTypeGroupChat;// 设置为群聊消息 | ||
//message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息 | //message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息 | ||
+ | </code> | ||
+ | |||
+ | ''3.8.9''以上版本的位置消息支持携带建筑物名称,携带建筑物名称的位置消息构造过程如下: | ||
+ | <code objc> | ||
+ | /*! | ||
+ | * \~chinese | ||
+ | * 初始化位置消息体 | ||
+ | * | ||
+ | * @param aLatitude 纬度 | ||
+ | * @param aLongitude 经度 | ||
+ | * @param aAddress 地理位置信息 | ||
+ | * @param aBuildingName 建筑物名称 | ||
+ | * | ||
+ | * @result 位置消息体实例 | ||
+ | * | ||
+ | * \~english | ||
+ | * Initialize a location message body instance | ||
+ | * | ||
+ | * @param aLatitude Latitude | ||
+ | * @param aLongitude Longitude | ||
+ | * @param aAddress Address | ||
+ | * @param aBuildingName BuildingName | ||
+ | * | ||
+ | * @result Location message body instance | ||
+ | */ | ||
+ | - (instancetype)initWithLatitude:(double)aLatitude | ||
+ | longitude:(double)aLongitude | ||
+ | address:(NSString *)aAddress | ||
+ | buildingName:(NSString *)aBuildingName; | ||
+ | </code> | ||
+ | 调用过程如下 | ||
+ | <code objc> | ||
+ | EMLocationMessageBody *body = [[EMLocationMessageBody alloc] initWithLatitude:39 longitude:116 address:@"weigh" buildingName:@"buildingName"]; | ||
</code> | </code> | ||
行 285: | 行 324: | ||
当 SDK 提供的消息类型不满足需求时,开发者可以通过扩展自 SDK 提供的文本、语音、图片、位置等消息类型,从而生成自己需要的消息类型。 | 当 SDK 提供的消息类型不满足需求时,开发者可以通过扩展自 SDK 提供的文本、语音、图片、位置等消息类型,从而生成自己需要的消息类型。 | ||
+ | |||
+ | ''Key值类型必须是NSString, Value值类型必须是NSString或者 NSNumber类型的 BOOL, int, unsigned in, long long, double'' | ||
这里是扩展自文本消息,如果这个自定义的消息需要用到语音或者图片等,可以扩展自语音、图片消息,亦或是位置消息。 | 这里是扩展自文本消息,如果这个自定义的消息需要用到语音或者图片等,可以扩展自语音、图片消息,亦或是位置消息。 | ||
行 465: | 行 506: | ||
</code> | </code> | ||
- | ==== 获取会话列表 ==== | + | ==== 获取本地会话列表 ==== |
<code objc> | <code objc> | ||
行 479: | 行 520: | ||
</code> | </code> | ||
+ | ==== 从服务器获取会话列表 ==== | ||
+ | ''需联系商务进行开通'' | ||
+ | |||
+ | 建议此api在首次安装应用时或者本地没有会话的时候调用,其他时候使用本地的会话api即可。默认最多返回100条数据。\\ | ||
+ | 使用该功能需要联系您的商务经理进行开通。(您可以在环信通讯云管理后台首页,扫描二维码联系您的商务经理) | ||
+ | <code> | ||
+ | [[EMClient sharedClient].chatManager getConversationsFromServer:^(NSArray *aCoversations, EMError *aError) { | ||
+ | if (!aError && [aCoversations count] > 0) { | ||
+ | //获取到会话列表后进行数据源装配和页面刷新 | ||
+ | } | ||
+ | }]; | ||
+ | </code> | ||
+ | ==== 获取会话中的所有消息计数 ==== | ||
+ | <code objc> | ||
+ | // 获取会话中的消息数,以单聊为例,群组、聊天室一样 | ||
+ | EMConversation *conversation = [[EMClient sharedClient].chatManager getConversation:@"8001" type:EMConversationTypeChat createIfNotExist:YES]; | ||
+ | [conversation messagesCount]; | ||
+ | </code> | ||
==== 获取单个会话未读消息数 ==== | ==== 获取单个会话未读消息数 ==== | ||
<code objc> | <code objc> | ||
+ | /*! | ||
+ | * \~chinese | ||
+ | * 获取一个会话 | ||
+ | * | ||
+ | * @param aConversationId 会话ID | ||
+ | * @param aType 会话类型 | ||
+ | * @param aIfCreate 如果不存在是否创建 | ||
+ | * | ||
+ | * @result 会话对象 | ||
+ | */ | ||
+ | - (EMConversation *)getConversation:(NSString *)aConversationId | ||
+ | type:(EMConversationType)aType | ||
+ | createIfNotExist:(BOOL)aIfCreate; | ||
+ | |||
+ | // 获取单聊会话的未读消息数 | ||
EMConversation *conversation = [[EMClient sharedClient].chatManager getConversation:@"8001" type:EMConversationTypeChat createIfNotExist:YES]; | EMConversation *conversation = [[EMClient sharedClient].chatManager getConversation:@"8001" type:EMConversationTypeChat createIfNotExist:YES]; | ||
+ | [conversation unreadMessagesCount]; | ||
+ | |||
+ | // 获取群聊会话的未读消息数 | ||
+ | EMConversation *conversation = [[EMClient sharedClient].chatManager getConversation:@"121828583195137" type:EMConversationTypeGroupChat createIfNotExist:YES]; | ||
[conversation unreadMessagesCount]; | [conversation unreadMessagesCount]; | ||
</code> | </code> | ||
行 704: | 行 782: | ||
</code> | </code> | ||
- | ==== 解析普通消息 ==== | + | ==== 解析普通消息(含自定义类型消息) ==== |
<code objc> | <code objc> | ||
行 786: | 行 864: | ||
NSLog(@"文件文件大小 -- %lld" ,body.fileLength); | NSLog(@"文件文件大小 -- %lld" ,body.fileLength); | ||
NSLog(@"文件文件的下载状态 -- %lu" ,body.downloadStatus); | NSLog(@"文件文件的下载状态 -- %lu" ,body.downloadStatus); | ||
+ | } | ||
+ | break; | ||
+ | case EMMessageBodyTypeCustom: | ||
+ | { | ||
+ | // 收到的自定义类型消息 | ||
+ | EMCustomMessageBody *body = (EMCustomMessageBody *)msgBody; | ||
+ | NSLog(@"event -- %@", body.event); | ||
+ | NSLog(@"ext -- %@", body.ext); | ||
} | } | ||
break; | break; | ||
行 875: | 行 961: | ||
}]; | }]; | ||
</code> | </code> | ||
+ | |||
+ | ==== 发送会话已读消息 ==== | ||
+ | |||
+ | * 功能描述:给服务器发送一条“会话已读”消息,表示当前会话的消息已读。 | ||
+ | * 使用场景: | ||
+ | 若当前会话有未读消息,则发送会话“已读”消息给服务器,服务器回调给多设备id或者会话方。 | ||
+ | * API使用示例: | ||
+ | <code objc> | ||
+ | if (self.conversation.unreadMessagesCount > 0) { | ||
+ | [[EMClient sharedClient].chatManager ackConversationRead:self.conversation.conversationId completion:nil]; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ==== 接收会话已读回调 ==== | ||
+ | |||
+ | * 功能描述:表示此会话的未读消息在其他登陆的多设备上“已读“,或会话方”已读“接收的未读消息。 | ||
+ | * 使用场景: | ||
+ | 当有我方多设备或会话方“发送会话已读消息”,则会收到会话已读回调,收到会话已读回调后可重新刷新未读数,消息已读相关UI。 | ||
+ | * API示例: | ||
+ | <code objc> | ||
+ | - (void)onConversationRead:(NSString *)from to:(NSString *)to; | ||
+ | </code> | ||
==== 消息已送达回执 ==== | ==== 消息已送达回执 ==== | ||
行 890: | 行 998: | ||
已读回执需要开发者主动调用的。当用户读取消息后,由开发者主动调用方法。 | 已读回执需要开发者主动调用的。当用户读取消息后,由开发者主动调用方法。 | ||
+ | 消息已读回执功能目前仅适用于单聊(ChatType.Chat),推荐使用方案为会话已读回执(conversation ack)+单条消息已读回执(read ack)结合实现,可减少发送read ack消息量。\\ | ||
+ | **''注:群消息已读回执功能为增值服务,具体使用请跳转到[[http://docs-im.easemob.com/im/ios/basics/message#设置群消息是否需要已读回执_增值服务|群消息已读回执]]。''** | ||
=== 发送已读回执 === | === 发送已读回执 === | ||
+ | 推荐进入会话首先发送会话已读回执(conversation ack) | ||
+ | <code objc> | ||
+ | [[EMClient sharedClient].chatManager ackConversationRead:@"会话id" completion:nil]; | ||
+ | </code> | ||
+ | 在会话页面,可以在接收到消息时,根据消息类型发送消息已读回执(read ack) | ||
<code objc> | <code objc> | ||
/*! | /*! | ||
行 920: | 行 1035: | ||
=== 接收已读回执 === | === 接收已读回执 === | ||
+ | 接收会话已读回执 | ||
+ | <code objc> | ||
+ | /** | ||
+ | * \~chinese | ||
+ | * 收到会话已读回调 | ||
+ | * | ||
+ | * @param from CHANNEL_ACK 发送方 | ||
+ | * @param to CHANNEL_ACK 接收方 | ||
+ | * | ||
+ | * \~english | ||
+ | * received conversation read ack | ||
+ | * @param from the username who send channel_ack | ||
+ | * @param to the username who receive channel_ack | ||
+ | */ | ||
+ | - (void)onConversationRead:(NSString *)from to:(NSString *)to; | ||
+ | </code> | ||
+ | 接收到会话已读回执(channel ack)回调后,SDK会将会话相关消息置为对方已读,在接收到此回调后,需进行页面刷新等操作 | ||
+ | |||
+ | 接收消息已读回执 | ||
<code objc> | <code objc> | ||
/*! | /*! | ||
行 998: | 行 1132: | ||
- (void)groupMessageDidRead:(EMMessage *)aMessage | - (void)groupMessageDidRead:(EMMessage *)aMessage | ||
groupAcks:(NSArray *)aGroupAcks; | groupAcks:(NSArray *)aGroupAcks; | ||
+ | </code> | ||
+ | |||
+ | |||
+ | ==== 获取群已读详情 ==== | ||
+ | |||
+ | <code> | ||
+ | /** | ||
+ | * \~chinese | ||
+ | * 从服务器获取指定群已读回执 | ||
+ | * | ||
+ | * 异步方法 | ||
+ | * | ||
+ | * @param aMessageId 要获取的消息id | ||
+ | * @param aGroupId 要获取回执对应的群id | ||
+ | * @param aGroupAckId 要回去的群回执id | ||
+ | * @param aPageSize 获取消息条数 | ||
+ | * @param aCompletionBlock 获取消息结束的callback | ||
+ | */ | ||
+ | - (void)asyncFetchGroupMessageAcksFromServer:(NSString *)aMessageId | ||
+ | groupId:(NSString *)aGroupId | ||
+ | startGroupAckId:(NSString *)aGroupAckId | ||
+ | pageSize:(int)aPageSize | ||
+ | completion:(void (^)(EMCursorResult *aResult, EMError *error, int totalCount))aCompletionBlock; | ||
</code> | </code> | ||
行 1013: | 行 1170: | ||
* @param aConversationType 要获取漫游消息的Conversation type | * @param aConversationType 要获取漫游消息的Conversation type | ||
* @param aStartMessageId 参考起始消息的ID | * @param aStartMessageId 参考起始消息的ID | ||
- | * @param aPageSize 获取消息条数 | + | * @param aPageSize 获取消息条数(一次最多50条) |
* @param aCompletionBlock 获取消息结束的callback | * @param aCompletionBlock 获取消息结束的callback | ||
*/ | */ | ||
行 1069: | 行 1226: | ||
注:消息撤回为增值功能,请联系环信商务开通。 | 注:消息撤回为增值功能,请联系环信商务开通。 | ||
+ | |||
+ | ==== 删除消息 ==== | ||
+ | SDK提供删除指定时间之前的所有本地消息的接口。调用过程如下 | ||
+ | <code objc> | ||
+ | /*! | ||
+ | * \~chinese | ||
+ | * 删除某个时间点之前的消息 | ||
+ | * | ||
+ | * 异步方法 | ||
+ | * | ||
+ | * @param aTimestamp 要删除时间点,单位毫秒 | ||
+ | * @param aCompletion 完成回调 | ||
+ | * | ||
+ | * \~english | ||
+ | * Delete messages which before a special timestamp | ||
+ | * | ||
+ | * | ||
+ | * @param aTimestamp The timestamp to delete | ||
+ | * @param aCompletion The callback block of completion | ||
+ | * | ||
+ | */ | ||
+ | - (void)deleteMessagesBefore:(NSUInteger)aTimestamp | ||
+ | completion:(void(^)(EMError*error))aCompletion; | ||
+ | </code> | ||
+ | 调用过程如下: | ||
+ | <code objc> | ||
+ | // 例如删除消息msg之前的所有消息 | ||
+ | [[EMClient sharedClient].chatManager deleteMessagesBefore:msg.timestamp completion:nil]; | ||
+ | </code> | ||
+ | |||
+ | ===== 翻译 ===== | ||
+ | |||
+ | 翻译功能使用微软翻译服务实现,用户可将文本翻译为所有微软翻译服务支持的语言,并提供译文存储功能。 | ||
+ | |||
+ | 使用翻译功能需要引入单独的EMTranslate.framework,可以通过在Podfile文件中添加**pod EMTranslate**引入,或直接将EMTranslate.framework拖入工程中。 | ||
+ | |||
+ | 使用翻译功能需要满足以下条件: | ||
+ | - 已完成环信IM''(3.8.9以上版本)''基本集成,账户登录成功 | ||
+ | - 已创建微软翻译服务资源,并获取到翻译参数,创建过程参见https://docs.microsoft.com/zh-cn/azure/cognitive-services/translator/translator-how-to-signup | ||
+ | |||
+ | 使用过程如下: | ||
+ | - 翻译模块初始化 | ||
+ | - 设置微软翻译服务参数 | ||
+ | - 获取支持的语言/翻译文本消息 | ||
+ | |||
+ | ==== 翻译模块初始化 ==== | ||
+ | |||
+ | 翻译模块初始化的过程中,会从本地数据库加载已有的译文到缓存中。调用过程如下 | ||
+ | <code> | ||
+ | [[EMTranslationManager sharedManager] initialize]; | ||
+ | </code> | ||
+ | |||
+ | ==== 设置微软翻译服务参数 ==== | ||
+ | 用户在翻译文本前,需要将创建微软翻译资源生成的参数(subscriptionKey、endpoint、location)设置到SDK中。设置过程如下: | ||
+ | <code> | ||
+ | EMMicrosoftTranslateParams* params = [[EMMicrosoftTranslateParams alloc] init]; | ||
+ | params.subscriptionKey = TRANSLATE_KEY; | ||
+ | params.endpoint = TRANSLATE_ENDPOINT; | ||
+ | params.location = TRANSLATE_LOCATION; | ||
+ | [[EMTranslationManager sharedManager] setTranslateParam:params]; | ||
+ | </code> | ||
+ | |||
+ | ==== 获取翻译服务支持的语言 ==== | ||
+ | SDK支持所有微软翻译服务支持的语言,获取支持的语言的过程如下: | ||
+ | <code> | ||
+ | [[EMTranslationManager sharedManager] fetchSupportedLangurages:^(NSArray<EMLanguage *> * _Nullable languages, EMError * _Nullable error) { | ||
+ | // 这里处理语言显示 | ||
+ | }]; | ||
+ | </code> | ||
+ | |||
+ | ==== 文本翻译 ==== | ||
+ | 设置完翻译参数后,用户可以调用消息翻译接口,进行翻译。每一条翻译信息,都有一个所属的会话conversationId,相当于译文所属的分组。翻译调用过程如下: | ||
+ | <code> | ||
+ | [[EMTranslationManager sharedManager] translateMessage:@"msgId" text:@"要翻译的文本内容" language:@"en-us" conversationId:@"会话ID" completion:^(EMTranslationResult * _Nullable msg, EMError * _Nullable err) { | ||
+ | }]; | ||
+ | </code> | ||
+ | |||
+ | 翻译成功之后,SDK会将译文存储到本地数据库。用户可根据译文的msgId从数据库获取译文,不存在则返回空。获取过程如下: | ||
+ | <code> | ||
+ | EMTranslationResult* result = [[EMTranslationManager sharedManager] getTranslationByMsgId:@"msgId"]; | ||
+ | </code> | ||
+ | |||
+ | ==== 退出 ==== | ||
+ | 当账户退出时,需要清理缓存中当前账户的译文信息,需要调用如下接口 | ||
+ | <code> | ||
+ | [[EMTranslationManager sharedManager] logout]; | ||
+ | </code> | ||
+ | |||
+ | ==== 进阶 ==== | ||
+ | |||
+ | SDK会将译文信息保存到本地数据库,当保存的译文太多时,会数据库文件增大,打开数据库变慢,因此需要定期进行清理。 | ||
+ | |||
+ | SDK提供了以下三种清理方式 | ||
+ | * 按会话清理译文 | ||
+ | 按会话清理译文方式如下: | ||
+ | <code> | ||
+ | [[EMTranslationManager sharedManager] removeTranslationByConversationId:@"conversationId"]; | ||
+ | </code> | ||
+ | |||
+ | * 按消息Id清理译文 | ||
+ | 按消息清理译文方式如下: | ||
+ | <code> | ||
+ | [[EMTranslationManager sharedManager] removeTranslationByMsgIds:@[@"msgId1",@"msgId2"]]; | ||
+ | </code> | ||
+ | |||
+ | * 清除所有译文 | ||
+ | 清理所有译文方式如下: | ||
+ | <code> | ||
+ | [[EMTranslationManager sharedManager] clearTranslations]; | ||
+ | </code> | ||
---- | ---- | ||
<WRAP group> | <WRAP group> |