差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
im:ios:basics:message [2020/06/25 02:41]
jliu
im:ios:basics:message [2022/03/11 10:31] (当前版本)
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>​
  
 +==== 从服务器获取会话列表 ====
 +''​该功能需联系商务开通,开通后,用户默认可拉取 7 天内的 10 个会话(每个会话包含最新一条历史消息),如需调整会话数量请联系环信商务经理(您可以在环信通讯云管理后台首页,扫描二维码联系您的商务经理)。''​
 +
 +建议此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>