李洪强iOS开发之-环信04_消息


消息:IM 交互实体,在 SDK 中对应的类型是 EMMessage。EMMessage 由 EMMessageBody 组成。

构造消息

 

构造文字消息

EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"要发送的消息"];
NSString *from = [[EMClient sharedClient] currentUsername];
 
//生成Message
EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt];
message.chatType = EMChatTypeChat;// 设置为单聊消息
//message.chatType = EMChatTypeGroupChat;// 设置为群聊消息
//message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息

构造图片消息

EMImageMessageBody *body = [[EMImageMessageBody alloc] initWithData:data displayName:@"image.png"];
NSString *from = [[EMClient sharedClient] currentUsername];
 
//生成Message
EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt];
message.chatType = EMChatTypeChat;// 设置为单聊消息
//message.chatType = EMChatTypeGroupChat;// 设置为群聊消息
//message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息

构造位置消息

EMLocationMessageBody *body = [[EMLocationMessageBody alloc] initWithLatitude:39 longitude:116 address:@"地址"];
NSString *from = [[EMClient sharedClient] currentUsername];
 
// 生成message
EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt];
message.chatType = EMChatTypeChat;// 设置为单聊消息
//message.chatType = EMChatTypeGroupChat;// 设置为群聊消息
//message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息

构造语音消息

EMVoiceMessageBody *body = [[EMVoiceMessageBody alloc] initWithLocalPath:@"audioPath" displayName:@"audio"];
body.duration = duration;
NSString *from = [[EMClient sharedClient] currentUsername];
 
// 生成message
EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt];
message.chatType = EMChatTypeChat;// 设置为单聊消息
//message.chatType = EMChatTypeGroupChat;// 设置为群聊消息
//message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息

构造视频消息

EMVideoMessageBody *body = [[EMVideoMessageBody alloc] initWithLocalPath:@"videoPath" displayName:@"video.mp4"];
NSString *from = [[EMClient sharedClient] currentUsername];
 
// 生成message
EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt];
message.chatType = EMChatTypeChat;// 设置为单聊消息
//message.chatType = EMChatTypeGroupChat;// 设置为群聊消息
//message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息

构造文件消息

EMFileMessageBody *body = [[EMFileMessageBody alloc] initWithLocalPath:@"filePath" displayName:@"file"];
NSString *from = [[EMClient sharedClient] currentUsername];
 
// 生成message
EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt];
message.chatType = EMChatTypeChat;// 设置为单聊消息
//message.chatType = EMChatTypeGroupChat;// 设置为群聊消息
//message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息

构造透传消息

SDK 提供的一种特殊类型的消息,即 CMD,不会存 db,也不会走 APNS 推送,类似一种指令型的消息。比如您的服务器要通知客户端做某些操作,您可以服务器和客户端提前约定好某个字段,当客户端收到约定好的字段时,执行某种特殊操作。

EMCmdMessageBody *body = [[EMCmdMessageBody alloc] initWithAction:action];
NSString *from = [[EMClient sharedClient] currentUsername];
 
// 生成message
EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt];
message.chatType = EMChatTypeChat;// 设置为单聊消息
//message.chatType = EMChatTypeGroupChat;// 设置为群聊消息
//message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息

构造扩展消息

当 SDK 提供的消息类型不满足需求时,开发者可以通过扩展自 SDK 提供的文本、语音、图片、位置等消息类型,从而生成自己需要的消息类型。

这里是扩展自文本消息,如果这个自定义的消息需要用到语音或者图片等,可以扩展自语音、图片消息,亦或是位置消息。

// 以单聊消息举例
EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"要发送的消息"];
NSString *from = [[EMClient sharedClient] currentUsername];
 
//生成Message
EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt];
message.chatType = EMChatTypeChat;// 设置为单聊消息
//message.chatType = EMChatTypeGroupChat;// 设置为群聊消息
//message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息
message.ext = @{@"key":@"value"}; // 扩展消息部分

插入消息

EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"要发送的消息"];
NSString *from = [[EMClient sharedClient] currentUsername];
 
//生成Message
EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt];
message.chatType = EMChatTypeChat;// 设置为单聊消息
//message.chatType = EMChatTypeGroupChat;// 设置为群聊消息
//message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息
 
[[EMClient sharedClient].chatManager importMessages:@[message]];

更新消息属性

/*!
* 更新消息到 DB
*
* @param aMessage 消息
*
* @result 是否成功
*/
- (BOOL)updateMessage:(EMMessage *)aMessage;
 
//调用:[[EMClient sharedClient].chatManager updateMessage:aMessage];

会话

会话:操作聊天消息 EMMessage 的容器,在 SDK 中对应的类型是 EMConversation。

新建/获取一个会话

根据 conversationId 创建一个 conversation。

[[EMClient sharedClient].chatManager getConversation:@"8001" type:EMConversationTypeChat createIfNotExist:YES];
//EMConversationTypeChat 单聊会话
//EMConversationTypeGroupChat 群聊会话
//EMConversationTypeChatRoom 聊天室会话
  • getConversation:创建与8001的会话
  • type:会话类型
  • createIfNotExist:不存在是否创建

删除会话

 

删除单个会话

[[EMClient sharedClient].chatManager deleteConversation:@"8001" deleteMessages:YES];
  • deleteConversation: 删除与8001的会话
  • deleteMessages: 删除会话中的消息

根据 conversationId 批量删除会话

[[EMClient sharedClient].chatManager deleteConversations:@[@"8001",@"8002"] deleteMessages:YES];
  • deleteConversations: 要删除的会话
  • deleteMessages: 删除会话中的消息

获取会话列表

SDK中提供了三种获取会会话列表的方法。

获取或创建

EMConversation *conversation = [[EMClient sharedClient].chatManager getConversation:@"8001" type:EMConversationTypeChat createIfNotExist:YES];
  • getConversation: 获取或创建与8001的会话
  • type:EMConversationTypeChat: 会话类型

获取内存中所有会话

NSArray *conversations = [[EMClient sharedClient].chatManager getAllConversations];

获取 DB 中的所有会话

NSArray *conversations = [[EMClient sharedClient].chatManager loadAllConversationsFromDB];

获取会话未读消息数

[EMConversation unreadMessagesCount];

消息检索

可以通过关键字、消息类型、开始结束时间检索某个会话中的消息。

/*!
* 从数据库获取指定类型的消息,取到的消息按时间排序,如果参考的时间戳为负数,则从最新消息向前取,如果 aLimit 是负数,则获取所有符合条件的消息
*
* @param aType 消息类型
* @param aTimestamp 参考时间戳
* @param aLimit 获取的条数
* @param aSender 消息发送方,如果为空则忽略
* @param aDirection 消息搜索方向
*
* @result 消息列表<EMMessage>
*/
- (NSArray *)loadMoreMessagesWithType:(EMMessageBodyType)aType
before:(long long)aTimestamp
limit:(int)aLimit
from:(NSString*)aSender
direction:(EMMessageSearchDirection)aDirection;
 
/*!
* 从数据库获取包含指定内容的消息,取到的消息按时间排序,如果参考的时间戳为负数,则从最新消息向前取,如果 aLimit 是负数,则获取所有符合条件的消息
*
* @param aKeywords 搜索关键字,如果为空则忽略
* @param aTimestamp 参考时间戳
* @param aLimit 获取的条数
* @param aSender 消息发送方,如果为空则忽略
* @param aDirection 消息搜索方向
*
* @result 消息列表<EMMessage>
*/
- (NSArray *)loadMoreMessagesContain:(NSString*)aKeywords
before:(long long)aTimestamp
limit:(int)aLimit
from:(NSString*)aSender
direction:(EMMessageSearchDirection)aDirection;
 
/*!
* 从数据库获取指定时间段内的消息,取到的消息按时间排序,为了防止占用太多内存,用户应当制定加载消息的最大数
*
* @param aStartTimestamp 毫秒级开始时间
* @param aEndTimestamp 结束时间
* @param aMaxCount 加载消息最大数
*
* @result 消息列表<EMMessage>
*
*/
- (NSArray *)loadMoreMessagesFrom:(long long)aStartTimestamp
to:(long long)aEndTimestamp
maxCount:(int)aMaxCount;

聊天

登录成功之后才能进行聊天操作。发消息时,单聊和群聊调用的是统一接口,区别只是要设置下 message.chatType。

发送消息

/*!
@property
@brief 发送消息
@discussion
异步方法
*/
- (void)asyncSendMessage:(EMMessage *)aMessage
progress:(void (^)(int progress))aProgress
completion:(void (^)(EMMessage *message,
EMError *error))aProgressCompletion;
 
//调用:[[EMClient sharedClient].chatManager asyncSendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {}];

接收消息

注册消息回调

//消息回调:EMChatManagerChatDelegate
//注册消息回调
[[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil];
//移除消息回调
[[EMClient sharedClient].chatManager removeDelegate:self];

在线普通消息会走以下回调:

/*!
@method
@brief 接收到一条及以上非cmd消息
*/
- (void)didReceiveMessages:(NSArray *)aMessages;

透传(cmd)在线消息会走以下回调:

/*!
@method
@brief 接收到一条及以上cmd消息
*/
- (void)didReceiveCmdMessages:(NSArray *)aCmdMessages;

解析普通消息

// 收到消息的回调,带有附件类型的消息可以用 SDK 提供的下载附件方法下载(后面会讲到)
- (void)didReceiveMessages:(NSArray *)aMessages
{
for (EMMessage *message in aMessages) {
EMMessageBody *msgBody = message.body;
switch (msgBody.type) {
case EMMessageBodyTypeText:
{
// 收到的文字消息
EMTextMessageBody *textBody = (EMTextMessageBody *)msgBody;
NSString *txt = textBody.text;
NSLog(@"收到的文字是 txt -- %@",txt);
}
break;
case EMMessageBodyTypeImage:
{
// 得到一个图片消息body
EMImageMessageBody *body = ((EMImageMessageBody *)msgBody);
NSLog(@"大图remote路径 -- %@" ,body.remotePath);
NSLog(@"大图local路径 -- %@" ,body.localPath); // // 需要使用sdk提供的下载方法后才会存在
NSLog(@"大图的secret -- %@" ,body.secretKey);
NSLog(@"大图的W -- %f ,大图的H -- %f",body.size.width,body.size.height);
NSLog(@"大图的下载状态 -- %lu",body.downloadStatus);
 
 
// 缩略图sdk会自动下载
NSLog(@"小图remote路径 -- %@" ,body.thumbnailRemotePath);
NSLog(@"小图local路径 -- %@" ,body.thumbnailLocalPath);
NSLog(@"小图的secret -- %@" ,body.thumbnailSecretKey);
NSLog(@"小图的W -- %f ,大图的H -- %f",body.thumbnailSize.width,body.thumbnailSize.height);
NSLog(@"小图的下载状态 -- %lu",body.thumbnailDownloadStatus);
}
break;
case EMMessageBodyTypeLocation:
{
EMLocationMessageBody *body = (EMLocationMessageBody *)msgBody;
NSLog(@"纬度-- %f",body.latitude);
NSLog(@"经度-- %f",body.longitude);
NSLog(@"地址-- %@",body.address);
}
break;
case EMMessageBodyTypeVoice:
{
// 音频sdk会自动下载
EMVoiceMessageBody *body = (EMVoiceMessageBody *)msgBody;
NSLog(@"音频remote路径 -- %@" ,body.remotePath);
NSLog(@"音频local路径 -- %@" ,body.localPath); // 需要使用sdk提供的下载方法后才会存在(音频会自动调用)
NSLog(@"音频的secret -- %@" ,body.secretKey);
NSLog(@"音频文件大小 -- %lld" ,body.fileLength);
NSLog(@"音频文件的下载状态 -- %lu" ,body.downloadStatus);
NSLog(@"音频的时间长度 -- %lu" ,body.duration);
}
break;
case EMMessageBodyTypeVideo:
{
EMVideoMessageBody *body = (EMVideoMessageBody *)msgBody;
 
NSLog(@"视频remote路径 -- %@" ,body.remotePath);
NSLog(@"视频local路径 -- %@" ,body.localPath); // 需要使用sdk提供的下载方法后才会存在
NSLog(@"视频的secret -- %@" ,body.secretKey);
NSLog(@"视频文件大小 -- %lld" ,body.fileLength);
NSLog(@"视频文件的下载状态 -- %lu" ,body.downloadStatus);
NSLog(@"视频的时间长度 -- %lu" ,body.duration);
NSLog(@"视频的W -- %f ,视频的H -- %f", body.thumbnailSize.width, body.thumbnailSize.height);
 
// 缩略图sdk会自动下载
NSLog(@"缩略图的remote路径 -- %@" ,body.thumbnailRemotePath);
NSLog(@"缩略图的local路径 -- %@" ,body.thumbnailLocalPath);
NSLog(@"缩略图的secret -- %@" ,body.thumbnailSecretKey);
NSLog(@"缩略图的下载状态 -- %lu" ,body.thumbnailDownloadStatus);
}
break;
case EMMessageBodyTypeFile:
{
EMFileMessageBody *body = (EMFileMessageBody *)msgBody;
NSLog(@"文件remote路径 -- %@" ,body.remotePath);
NSLog(@"文件local路径 -- %@" ,body.localPath); // 需要使用sdk提供的下载方法后才会存在
NSLog(@"文件的secret -- %@" ,body.secretKey);
NSLog(@"文件文件大小 -- %lld" ,body.fileLength);
NSLog(@"文件文件的下载状态 -- %lu" ,body.downloadStatus);
}
break;
 
default:
break;
}
}
}

解析透传消息

- (void)didReceiveCmdMessages:(NSArray *)aCmdMessages{
for (EMMessage *message in aCmdMessages) {
EMCmdMessageBody *body = (EMCmdMessageBody *)message.body;
NSLog(@"收到的action是 -- %@",body.action);
}
}

解析消息扩展属性

- (void)didReceiveCmdMessages:(NSArray *)aCmdMessages{
for (EMMessage *message in aCmdMessages) {
// cmd消息中的扩展属性
NSDictionary *ext = message.ext;
NSLog(@"cmd消息中的扩展属性是 -- %@",ext)
}
}
// 收到消息回调
- (void)didReceiveMessages:(NSArray *)aMessages{
for (EMMessage *message in aMessages) {
// 消息中的扩展属性
NSDictionary *ext = message.ext;
NSLog(@"消息中的扩展属性是 -- %@",ext);
}
}

自动下载消息中的附件

SDK 接收到消息后,会默认下载:图片消息的缩略图,语音消息的语音,视频消息的视频第一帧。

请先判断你要下载附件没有下载成功之后,在调用以下下载方法,否则SDK下载方法会再次从服务器上获取附件。

[[EMClient sharedClient].chatManager asyncDownloadMessageThumbnail:message progress:nil completion:^(EMMessage *message, EMError *error) {
if (!error) {
NSLog(@"下载成功,下载后的message是 -- %@",aMessage);
}
}];

下载消息中的原始附件

[[EMClient sharedClient].chatManager asyncDownloadMessageAttachments:message progress:nil completion:^(EMMessage *message, EMError *error) {
if (!error) {
NSLog(@"下载成功,下载后的message是 -- %@",aMessage);
}
}];

消息已送达回执

SDK提供了已送达回执,当对方收到您的消息后,您会收到以下回调。

/*!
@method
@brief 接收到一条及以上已送达回执
*/
- (void)didReceiveHasDeliveredAcks:(NSArray *)aMessages;

消息已读回执

已读回执需要开发者主动调用的。当用户读取消息后,由开发者主动调用方法。

发送已读回执

// 发送已读回执。在这里写只是为了演示发送,在APP中具体在哪里发送需要开发者自己决定。
[[EMClient sharedClient].chatManager asyncSendReadAckForMessage:message];

接收已读回执

/*!
* 接收到一条及以上已读回执
*
* @param aMessages 消息列表<EMMessage>
*/
- (void)didReceiveHasReadAcks:(NSArray *)aMessages;

李洪强iOS开发之-环信04_消息的更多相关文章

  1. 李洪强iOS开发之-环信05_EaseUI 使用指南

    李洪强iOS开发之-环信05_EaseUI 使用指南 EaseUI 使用指南 简介 EaseUI 封装了 IM 功能常用的控件(如聊天会话.会话列表.联系人列表).旨在帮助开发者快速集成环信 SDK. ...

  2. 李洪强iOS开发之-环信03_集成 SDK 基础功能

    李洪强iOS开发之-环信03_集成 SDK 基础功能 集成 SDK 基础功能 在您阅读此文档时,我们假定您已经具备了基础的 iOS 应用开发经验,并能够理解相关基础概念. SDK 同步/异步方法区分 ...

  3. 李洪强iOS开发之-环信02.2_环信官网下载环信 SDK

    李洪强iOS开发之-环信02.2_环信官网下载环信 SDK 移动客服即时通讯云 iOS SDK 当前版本:V3.1.4 2016-07-08 [ 版本历史 ] | 开发指南 | 知识库 | Demo源 ...

  4. 李洪强iOS开发之-环信02.1_环信 SDK 2.x到3.0升级文档

    李洪强iOS开发之-环信02.1_环信 SDK 2.x到3.0升级文档 SDK 2.x 至 3.0 升级指南 环信 SDK 3.0 升级文档 3.0 中的核心类为 EMClient 类,通过 EMCl ...

  5. 李洪强iOS开发之-环信02_iOS SDK 介绍及导入

    李洪强iOS开发之-环信02_iOS SDK 介绍及导入 iOS SDK 介绍及导入 iOS SDK 介绍 环信 SDK 为用户开发 IM 相关的应用提供的一套完善的开发框架.包括以下几个部分: SD ...

  6. 李洪强iOS开发之-环信01_iOS SDK 前的准备工作

    李洪强iOS开发之-环信01_iOS SDK 前的准备工作 1.1_注册环信开发者账号并创建后台应用 详细步骤:  注册并创建应用 注册环信开发者账号 第 1 步:在环信官网上点击“即时通讯云”,并点 ...

  7. 李洪强iOS开发之-环信02.3_具体接口讲解 - Apple Docs

    http://www.easemob.com/apidoc/ios/chat3.0/annotated.html Apple Docs.

  8. 李洪强iOS开发本人集成环信的经验总结_01环信SDK的导入

    李洪强iOS开发本人集成环信的经验总结_01环信SDK的导入 01 - 直接在项目中导入SDK和一些静态库 这个时候,没有错误的编译没有错误的话,就说明SDK已经配置成功 还有一种方法是用cocoap ...

  9. 李洪强iOS开发本人集成环信的经验总结_03_注册

    李洪强iOS开发本人集成环信的经验总结_03_注册 环信一共提供了三种注册的方法:  01 同步注册:  02 异步注册:  03 - 使用代理回调进行注册,但是3.0没有了,3.0之前有  调用注册 ...

随机推荐

  1. poj2337 欧拉路径

    poj2337 这道题昨天晚上开始做,今天才A.但是问题想透了, 发现其实没那么难 题目大意: 给你一些单词,如果一个单词的末尾字符与另一个单词首字符相同,则两个的单词可以连接.问是否可以把所有单词连 ...

  2. C# string.Format格式化时间或货币

    1.格式化货币(跟系统的环境有关,中文系统默认格式化人民币,英文系统格式化美元) string.Format("{0:C}",0.2) 结果为:¥0.20 (英文操作系统结果:$0 ...

  3. ios Swift 备忘录

    Variables var myInt = var myExplicitInt: Int = // explicit type var x = , y = , z = // declare multi ...

  4. 一个layer可以跟着画完的线移动ios程序 好玩啊。

    用法:采用的是关键帧实现的. 实验目的:让上层的layer子层能够跟着在另一个子层上花的线进行移动 .即当线画完之后,图形开始移动,并且能够停在最后的那个位置 效果图: 采用是直接在layer图层上进 ...

  5. (hdu)2444 The Accomodation of Students 判断二分图+最大匹配数

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2444 Problem Description There are a group of s ...

  6. 在Linux系统下安装大于mysql5.5版本的数据库

    linux下mysql 5.5的安装方法: 1.安装所需要系统库相关库文件      gcc等开发包,在安装linux系统的时候安装. 2.创建mysql安装目录 # mkdir -p /usr/lo ...

  7. bat文件的妙用1-一键开启所有开发软件

    每天早上来的第一件事情,就是打开电脑,然后开一堆的软件 1.wamp 开发环境 2.钉钉   通讯工具 3.PHPstrom 开发工具 4.nodejs.bat Nodejs的扩展(node D:/w ...

  8. java Object类

    常用的共性内容 1,实现任何对象的比较,一般比较同一种对象的比较 Object1.equals(Object obj);等同于Object1 == obj: 只有当两个引用指向同一个对象时方法返回tr ...

  9. Oracle Database does not provide any supplemental logging, which means that by default LogMiner is not usable

    写在前面,在研究Oracle logmnr 的时候看到 http://www.askmaclean.com/archives/dbms_logmnr-unsupported-sqlredo.html ...

  10. python初准备:安装easy_install和pip

    安装easy_install wget http://peak.telecommunity.com/dist/ez_setup.py python ez_setup.py 安装pip wget htt ...