环信creo2.0警告消息列表表怎么显示的都是用户的uid,怎么改呢

2237人阅读
iOS学习—环信(27)
1.在消息控制器获取历史回话记录/**
获取历史会话对象记录
- (void)loadConversations
// 当前登录用户回话对象列表
NSArray *conversations = [[EaseMob sharedInstance].chatManager conversations];
if (conversations.count == 0) {
// 从数据库conversation表获取
conversations = [[EaseMob sharedInstance].chatManager loadAllConversationsFromDatabaseWithAppend2Chat:YES];
self.conversations =
// 显示总的未读数
[self showTabBarBadge];
#pragma mark - EMChatManagerChatDelegate
历史会话列表更新了会调用
- (void)didUpdateConversationList:(NSArray *)conversationList
// 给数据源重新赋值
self.conversations = conversationL
// 刷新表格
[self.tableView reloadData];
// 显示总的未读数
[self showTabBarBadge];
未读消息数改变了会调用
- (void)didUnreadMessagesCountChanged
[self.tableView reloadData];
// 显示总的未读数
[self showTabBarBadge];
将总的未读消息数显示到tabBar上
- (void)showTabBarBadge
NSInteger totalUnreadCount = 0;
for (EMConversation *conversation in self.conversations) {
totalUnreadCount += [conversation unreadMessagesCount];
self.navigationController.tabBarItem.badgeValue = [NSString stringWithFormat:@&%ld&,totalUnreadCount];
}2.消息控制器完整代码//
MessageViewController.m
#import &MessageViewController.h&
#import &EaseMob.h&
#import &ChatViewController.h&
@interface MessageViewController ()&EMChatManagerDelegate&
历史会话对象列表
@property(nonatomic,strong)NSArray *
@implementation MessageViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 设置标题
self.title = @&消息&;
// 添加聊天管理器的代理
[[EaseMob sharedInstance].chatManager addDelegate:self delegateQueue:nil];
// 获取历史回话记录
[self loadConversations];
- (void)dealloc
// 移除聊天管理器的代理
[[EaseMob sharedInstance].chatManager removeDelegate:self];
获取历史会话对象记录
- (void)loadConversations
// 当前登录用户回话对象列表
NSArray *conversations = [[EaseMob sharedInstance].chatManager conversations];
if (conversations.count == 0) {
// 从数据库conversation表获取
conversations = [[EaseMob sharedInstance].chatManager loadAllConversationsFromDatabaseWithAppend2Chat:YES];
self.conversations =
// 显示总的未读数
[self showTabBarBadge];
#pragma mark - EMChatManagerChatDelegate
历史会话列表更新了会调用
- (void)didUpdateConversationList:(NSArray *)conversationList
// 给数据源重新赋值
self.conversations = conversationL
// 刷新表格
[self.tableView reloadData];
// 显示总的未读数
[self showTabBarBadge];
未读消息数改变了会调用
- (void)didUnreadMessagesCountChanged
[self.tableView reloadData];
// 显示总的未读数
[self showTabBarBadge];
将总的未读消息数显示到tabBar上
- (void)showTabBarBadge
NSInteger totalUnreadCount = 0;
for (EMConversation *conversation in self.conversations) {
totalUnreadCount += [conversation unreadMessagesCount];
self.navigationController.tabBarItem.badgeValue = [NSString stringWithFormat:@&%ld&,totalUnreadCount];
@brief 将要发起自动重连操作时发送该回调
@discussion
- (void)willAutoReconnect
self.title = @&网络连接中...&;
@brief 自动重连操作完成后的回调(成功的话,error为nil,失败的话,查看error的错误信息)
@discussion
- (void)didAutoReconnectFinishedWithError:(NSError *)error
if (!error) {
self.title = @&消息&;
监听网络状态
- (void)didConnectionStateChanged:(EMConnectionState)connectionState{
eEMConnectionConnected,
//连接成功
eEMConnectionDisconnected,//未连接
if (connectionState == eEMConnectionDisconnected) {
NSLog(@&网络断开,未连接...&);
self.title = @&未连接.&;
NSLog(@&网络通了...&);
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return self.conversations.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
// 创建cell
static NSString *ID = @&messageCell&;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
// 设置cell上显示的数据
EMConversation *conversation = self.conversations[indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:@&%@ 未读:%ld&,conversation.chatter,conversation.unreadMessagesCount];
id body = conversation.latestMessage.messageBodies[0];
if ([body isKindOfClass:[EMTextMessageBody class]]) {
EMTextMessageBody *textBody =
cell.detailTextLabel.text = textBody.
}else if ([body isKindOfClass:[EMVideoMessageBody class]]){
EMVideoMessageBody *voiceBody =
cell.detailTextLabel.text = [voiceBody displayName];
}else if ([body isKindOfClass:[EMImageMessageBody class]]){
EMImageMessageBody *imgBody =
cell.detailTextLabel.text = imgBody.displayN
cell.detailTextLabel.text = @&未知消息类型&;
#pragma mark - UITabelViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
// 从storyboard加载聊天控制器
ChatViewController *chatVc = [[UIStoryboard storyboardWithName:@&Main& bundle:nil] instantiateViewControllerWithIdentifier:@&chatPage&];
// 设置好友属性
EMConversation *conversation = self.conversations[indexPath.row];
EMBuddy *buddy = [EMBuddy buddyWithUsername:conversation.chatter];
chatVc.buddy =
// 跳转到聊天控制器
[self.navigationController pushViewController:chatVc animated:YES];
3.从消息控制器跳转到聊天控制器
消息控制器中实现
#pragma mark - UITabelViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
// 从storyboard加载聊天控制器
ChatViewController *chatVc = [[UIStoryboard storyboardWithName:@&Main& bundle:nil] instantiateViewControllerWithIdentifier:@&chatPage&];
// 设置好友属性
EMConversation *conversation = self.conversations[indexPath.row];
EMBuddy *buddy = [EMBuddy buddyWithUsername:conversation.chatter];
chatVc.buddy =
// 跳转到聊天控制器
[self.navigationController pushViewController:chatVc animated:YES];
}4.聊天控制器里需要标识消息为已读,聊天控制器完整代码//
ChatViewController.m
Created by yongkaidong on 16/2/13.
Copyright © 2016年 com.yongkaidong. All rights reserved.
#import &ChatViewController.h&
#import &ChatCell.h&
#import &EaseMob.h&
#import &EMCDDeviceManager.h&
#import &AudioPlayTool.h&
#import &TimeCell.h&
#import &TimeTool.h&
@interface ChatViewController ()&UITableViewDataSource,UITableViewDelegate,UITextViewDelegate,EMChatManagerDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate&
inputToolbar(输入工具栏)底部的约束
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *inputToolbarBottomC
inputToolbar高度的约束
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *inputToolbarHeightC
@property (weak, nonatomic) IBOutlet UIButton *recordB
@property (weak, nonatomic) IBOutlet UIButton *voiceB
@property (weak, nonatomic) IBOutlet UITextView *textV
里边存的都是消息模型
@property(nonatomic,strong)NSMutableArray *dataS
@property (weak, nonatomic) IBOutlet UITableView *tableV
专门用来计算高度的cell工具对象
@property(nonatomic,strong) ChatCell *chatCellT
当前添加的时间字符串
@property(nonatomic,copy)NSString *currentTimeS
当前会话对象
@property(nonatomic,strong)EMConversation *
@implementation ChatViewController
- (NSMutableArray *)dataSources
if (!_dataSources) {
_dataSources = [NSMutableArray array];
return _dataS
懒加载创建chatCellTool
- (ChatCell *)chatCellTool
if (!_chatCellTool) {
//Identifier 用recivierCell或senderCell都可以,因为2个cell其实内部
//Identifier 声明在cell内部的
_chatCellTool = [self.tableView dequeueReusableCellWithIdentifier:senderCell];
return _chatCellT
- (void)viewDidLoad {
[super viewDidLoad];
// 0.设置标题
self.title = self.buddy.
// 1.监听键盘的弹出
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
// 2.监听键盘的退出
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
// 3.加载本地数据库的聊天记录
[self loadLocalChatRecords];
// 4.设置聊天管理器的代理
[[EaseMob sharedInstance].chatManager addDelegate:self delegateQueue:nil];
// 5.tableView滚动到最底部
[self scrollToBottom];
加载本地的聊天记录
- (void)loadLocalChatRecords
// 获取本地聊天记录 使用回话对象
EMConversation *conversation = [[EaseMob sharedInstance].chatManager conversationForChatter:self.buddy.username conversationType:eConversationTypeChat];
self.conversation =
// 加载与当前聊天用户的所有聊记录
NSArray *messages = [conversation loadAllMessages];
// 添加到数据源
for (EMMessage *msg in messages) {
[self addDataSourcesWithMessage:msg];
键盘退出会调用
- (void)keyboardWillHide:(NSNotification *)notice
// inputToolbar回到原位
self.inputToolbarBottomConstraint.constant = 0;
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
键盘弹出会调用
- (void)keyboardWillShow:(NSNotification *)notice
// 1.获取键盘高度
CGFloat heigth = [notice.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.
// 2.更改inputToolbar底部约束
self.inputToolbarBottomConstraint.constant =
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
// 3.滚动tableView
[self scrollToBottom];
添加通知要移除,我们可以在这里方法里移除
- (void)dealloc
[[NSNotificationCenter defaultCenter] removeObserver:self];
#pragma mark -UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return self.dataSources.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//判断数据源类型
if ([self.dataSources[indexPath.row] isKindOfClass:[NSString class]]) {
TimeCell *cell = [tableView dequeueReusableCellWithIdentifier:@&timeCell&];
cell.timeLabel.text = self.dataSources[indexPath.row];
// 1.获取消息模型
EMMessage *message = self.dataSources[indexPath.row];
// 2.创建cell
ChatCell *cell =
if ([message.from isEqualToString:self.buddy.username]) { //好友
cell = [tableView dequeueReusableCellWithIdentifier:recivierCell];
}else{ //自己
cell = [tableView dequeueReusableCellWithIdentifier:senderCell];
// 3.给cell传递数据模型
cell.message =
#pragma mark - UITableViewDelegate
返回cell的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
// 时间cell的高度是固定的
if ([self.dataSources[indexPath.row] isKindOfClass:[NSString class]]) {
return 20;
// 1.获取消息模型传递给cell,让cell有了数据然后调整布局
EMMessage *msg = self.dataSources[indexPath.row];
self.chatCellTool.message =
// 2.必须上面cell有了数据调整完布局,才能得到高度
return [self.chatCellTool cellHeight];
#pragma mark - UITableViewDelegate
开始滑动scrollView会调用
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
// 停止语音播放
[AudioPlayTool stop];
#pragma mark - UITextViewDelegate
- (void)textViewDidChange:(UITextView *)textView
// 1.计算textView的高度,调整整个inputToolbar的高度
CGFloat textViewH = 0;
CGFloat minH = 33; //textView最小高度
CGFloat maxH = 68; //textView最大高度
CGFloat contentH = textView.contentSize.
if (contentH & minH) {
textViewH = minH;
}else if (contentH & maxH){
textViewH = maxH;
textViewH = contentH;
// 2.监听用户是否点击了键盘的&Send&按钮 -- 判断最后一个字符是否是换行符
if ([textView.text hasSuffix:@&\n&]) {
// 发送消息
[self sendText:textView.text];
// 清空textView中的文字
textView.text =
// 用户点击&发送&之后,textView高度还原
textViewH = minH;
// 3.调整整个inputToolbar的高度
7为textView到顶部的距离
6为textView到底部的距离
self.inputToolbarHeightConstraint.constant = 7 + 6 + textViewH;
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
// 4.让光标回到原位
[textView setContentOffset:CGPointZero animated:YES];
[textView scrollRangeToVisible:textView.selectedRange];
#pragma mark - 发送消息(文本、语音、图片)
@param body 消息体
- (void)sendMessage:(id&IEMMessageBody&)body
// 1.构造消息对象
EMMessage *msg = [[EMMessage alloc] initWithReceiver:self.buddy.username bodies:@[body]];
msg.messageType = eMessageTypeC
// 2.发送消息
[[EaseMob sharedInstance].chatManager asyncSendMessage:msg progress:nil prepare:^(EMMessage *message, EMError *error) {
// 准备发送
} onQueue:nil completion:^(EMMessage *message, EMError *error) {
// 发送成功
} onQueue:nil];
// 4.把消息添加到数据源
[self addDataSourcesWithMessage:msg];
// 5.刷新表格
[self.tableView reloadData];
// 6.滚动tableView
[self scrollToBottom];
发送文本消息
- (void)sendText:(NSString *)text
// 0.处理字符串中的换行符
text = [text substringToIndex:text.length -1];
// 1.准备创建消息实例需要的参数
EMChatText *chatText = [[EMChatText alloc] initWithText:text];
EMTextMessageBody *textBody = [[EMTextMessageBody alloc] initWithChatObject:chatText];
[self sendMessage:textBody];
发送语音消息
@param recordPath 语音文件路径
@param duration
- (void)sendVoice:(NSString *)recordPath duration:(NSInteger)duration
// 1.构造一个 语音消息体
EMChatVoice *chatVoice = [[EMChatVoice alloc] initWithFile:recordPath displayName:@&[语音]&];
EMVoiceMessageBody *voiceBody = [[EMVoiceMessageBody alloc] initWithChatObject:chatVoice];
voiceBody.duration =
[self sendMessage:voiceBody];
发送图片消息
- (void)sendImage:(UIImage *)selectedImage
// 1.构造图片消息体
EMChatImage *orginalChatImg = [[EMChatImage alloc] initWithUIImage:selectedImage displayName:@&[图片]&];
EMImageMessageBody *imgBody = [[EMImageMessageBody alloc]initWithImage:orginalChatImg thumbnailImage:nil];
[self sendMessage:imgBody];
tableView滚动到最后一行
- (void)scrollToBottom
if (self.dataSources.count == 0)
NSIndexPath *lastIndex = [NSIndexPath indexPathForRow:self.dataSources.count-1 inSection:0];
[self.tableView scrollToRowAtIndexPath:lastIndex atScrollPosition:UITableViewScrollPositionBottom animated:YES];
#pragma mark - EMChatManagerDelegate
接收好友回复消息
- (void)didReceiveMessage:(EMMessage *)message
if ([message.from isEqualToString:self.buddy.username]) {
// 把好友回复的消息添加到数据源
[self addDataSourcesWithMessage:message];
// 刷新表格
[self.tableView reloadData];
// 滚动tablView
[self scrollToBottom];
#pragma mark - action
点击上传图片
- (IBAction)showImgPickerAction:(UIButton *)sender
// 图片选择控制器
UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];
imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoL
imgPicker.delegate =
[self presentViewController:imgPicker animated:YES completion:nil];
#pragma mark - UIImagePickerControllerDelegate
用户选中图片的回调
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary&NSString *,id& *)info
// 获取选中的图片
UIImage *selectedImg = info[UIImagePickerControllerOriginalImage];
// 发送图片消息
[self sendImage:selectedImg];
// 退出当前图片选择的控制器
[self dismissViewControllerAnimated:YES completion:nil];
VoiceBtn被点击了
- (IBAction)clickedVoiceBtn:(UIButton *)sender
// 按钮图片切换
self.voiceBtn.selected = !self.voiceBtn.
self.textView.hidden = !self.textView.
// 1.显示录音按钮
self.recordBtn.hidden = !self.recordBtn.
if (self.recordBtn.hidden == NO) { //录音按钮要显示
// inputToolbar的高度要回到默认高度
self.inputToolbarHeightConstraint.constant = 46;
// 退出键盘
[self.view endEditing:YES];
// 当不录音的时候,键盘显示
[self.textView becomeFirstResponder];
// 恢复inputToolbar的高度
[self textViewDidChange:self.textView];
手指按下去开始录音
- (IBAction)touchDownRecordBtn:(id)sender
// 文件名以时间命令
int x = arc4random() % 100000;
NSTimeInterval time = [[NSDate date] timeIntervalSince1970];
NSString *fileName = [NSString stringWithFormat:@&%d%d&,(int)time,x];
[[EMCDDeviceManager sharedInstance] asyncStartRecordingWithFileName:fileName completion:^(NSError *error) {
if (!error) {
//开始录音成功
手指松开结束录音
- (IBAction)touchUpInsideRecordBtn:(id)sender
[[EMCDDeviceManager sharedInstance] asyncStopRecordingWithCompletion:^(NSString *recordPath, NSInteger aDuration, NSError *error) {
if (!error) {
//录音完成
//发送语音
[self sendVoice:recordPath duration:aDuration];
手指从按钮的外面松开结束录音
- (IBAction)touchUpOutsideRecordBtn:(id)sender
加入数据源的方法
- (void)addDataSourcesWithMessage:(EMMessage *)message
// 1.判断EMMessage对象前面是否要加『时间』
NSString *timeStr = [TimeTool timeStr:message.timestamp];
if (![self.currentTimeStr isEqualToString:timeStr]) {
[self.dataSources addObject:timeStr];
self.currentTimeStr = timeS
// 2.再加EMMessage
[self.dataSources addObject:message];
// 3.设置消息为已读
[self.conversation markMessageWithId:message.messageId asRead:YES];
自此,环信项目已完结!
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:292505次
积分:12879
积分:12879
排名:第800名
原创:994篇
转载:144篇
评论:28条
(21)(60)(76)(27)(57)(96)(80)(33)(14)(40)(83)(83)(82)(106)(36)(26)(41)(82)(44)(26)(19)(24)(7)老人有些困倦,将双脚伸进了炉堂取暖。
哪知气温骤降,海浪一波波往上冲刷着车辆。
声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
  因为遇到了不少用户问到了这个问题,所以在这里总结一下。
  首先明确一下,环信只是即时通讯的消息引擎。环信本身不提供用户体系,环信既不保存任何APP业务数据,也不保存任何APP的用户信息。
  根据环信ID来绑定用户的昵称,头像,方便维护。 环信3.0 demo中,是用parse来管理昵称,头像的(parse是管理昵称,头像的一个三方库,将头像,昵称上传到parse服务器,在从parse服务器获取),从自己服务器获取的话就按照下面的方法参考一下吧。
  1. 服务器维护昵称,头像的方案先看下这个链接:
  2. 从自己服务器获取到用户的昵称,头像后,会话列表类的替换,在EaseConversationCell.m类,- (void)setModel:(id&IConversationModel&)model中 [self.avatarView.imageView sd_setImageWithURL:[NSURL URLWithString:_model.avatarURLPath] placeholderImage:_model.avatarImage]; 这个方法就是来展示头像的
  3. 聊天类的替换,在EaseBaseMessageCell.m类,- (void)setModel:(id&IMessageModel&)model中
  if (model.isSender) {
  UIImage *placeholderImage = [UIImage imageNamed:@&123&];
  self.avatarView.image = placeholderI
  } else {
  if (model.avatarURLPath) {
  [self.avatarView sd_setImageWithURL:[NSURL URLWithString:model.avatarURLPath] placeholderImage:model.avatarImage];
  } else {
  self.avatarView.image = model.avatarI
  if (model.isSender) 我自己加的判断 区分发送者和接受者的头像(isSender判断是不是当前登录者),如果想在这个类中想要获取到对方的环信ID,那么引入 #import &EMMessage.h&头文件, EMMessage *message = model. NSString *username = message.就可以获取到了,然后自己在根据环信ID自己做处理,展示。
  4.联系人类的替换,在EaseUserCell.m类,- (void)setModel:(id&IUserModel&)model中,self.titleLabel.text = _model.buddy. [self.avatarView.imageView sd_setImageWithURL:[NSURL URLWithString:_model.avatarURLPath] placeholderImage:_model.avatarImage];
欢迎举报抄袭、转载、暴力色情及含有欺诈和虚假信息的不良文章。
请先登录再操作
请先登录再操作
微信扫一扫分享至朋友圈
搜狐公众平台官方账号
生活时尚&搭配博主 /生活时尚自媒体 /时尚类书籍作者
搜狐网教育频道官方账号
全球最大华文占星网站-专业研究星座命理及测算服务机构
提供云企业热点信息
主演:黄晓明/陈乔恩/乔任梁/谢君豪/吕佳容/戚迹
主演:陈晓/陈妍希/张馨予/杨明娜/毛晓彤/孙耀琦
主演:陈键锋/李依晓/张迪/郑亦桐/张明明/何彦霓
主演:尚格?云顿/乔?弗拉尼甘/Bianca Bree
主演:艾斯?库珀/ 查宁?塔图姆/ 乔纳?希尔
baby14岁写真曝光
李冰冰向成龙撒娇争宠
李湘遭闺蜜曝光旧爱
美女模特教老板走秀
曝搬砖男神奇葩择偶观
柳岩被迫成赚钱工具
大屁小P虐心恋
匆匆那年大结局
乔杉遭粉丝骚扰
男闺蜜的尴尬初夜
客服热线:86-10-
客服邮箱:3213人阅读
iOS学习—环信(27)
1.在聊天控制器连线
点击上传图片
- (IBAction)showImgPickerAction:(UIButton *)sender
// 图片选择控制器
UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];
imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoL
imgPicker.delegate =
[self presentViewController:imgPicker animated:YES completion:nil];
}2.遵守协议
UIImagePickerControllerDelegate,UINavigationControllerDelegate
实现代理方法:#pragma mark - UIImagePickerControllerDelegate
用户选中图片的回调
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary&NSString *,id& *)info
// 获取选中的图片
UIImage *selectedImg = info[UIImagePickerControllerOriginalImage];
// 发送图片消息
[self sendImage:selectedImg];
// 退出当前图片选择的控制器
[self dismissViewControllerAnimated:YES completion:nil];
}&具体发送图片的方法:/**
发送图片消息
- (void)sendImage:(UIImage *)selectedImage
// 构造图片消息体
EMChatImage *orginalChatImg = [[EMChatImage alloc] initWithUIImage:selectedImage displayName:@&[图片]&];
EMImageMessageBody *imgBody = [[EMImageMessageBody alloc]initWithImage:orginalChatImg thumbnailImage:nil];
// 构造图片消息对象
EMMessage *msg = [[EMMessage alloc] initWithReceiver:self.buddy.username bodies:@[imgBody]];
msg.messageType = eMessageTypeC
[[EaseMob sharedInstance].chatManager asyncSendMessage:msg progress:nil prepare:^(EMMessage *message, EMError *error) {
// 准备发送图片
} onQueue:nil completion:^(EMMessage *message, EMError *error) {
// 发送图片成功
} onQueue:nil];
// 4.把消息添加到数据源,然后刷新表格
[self.dataSources addObject:msg];
[self.tableView reloadData];
// 5.滚动tableView
[self scrollToBottom];
}自此,图片的发送完成。
二.代码优化
发送图片,发送文本,发送语音,这都有大量重复代码,我们稍加优化
#pragma mark - 发送消息(文本、语音、图片)
@param body 消息体
- (void)sendMessage:(id&IEMMessageBody&)body
// 1.构造消息对象
EMMessage *msg = [[EMMessage alloc] initWithReceiver:self.buddy.username bodies:@[body]];
msg.messageType = eMessageTypeC
// 2.发送消息
[[EaseMob sharedInstance].chatManager asyncSendMessage:msg progress:nil prepare:^(EMMessage *message, EMError *error) {
// 准备发送
} onQueue:nil completion:^(EMMessage *message, EMError *error) {
// 发送成功
} onQueue:nil];
// 4.把消息添加到数据源
[self.dataSources addObject:msg];
// 5.刷新表格
[self.tableView reloadData];
// 6.滚动tableView
[self scrollToBottom];
发送文本消息
- (void)sendText:(NSString *)text
// 0.处理字符串中的换行符
text = [text substringToIndex:text.length -1];
// 1.准备创建消息实例需要的参数
EMChatText *chatText = [[EMChatText alloc] initWithText:text];
EMTextMessageBody *textBody = [[EMTextMessageBody alloc] initWithChatObject:chatText];
[self sendMessage:textBody];
发送语音消息
@param recordPath 语音文件路径
@param duration
- (void)sendVoice:(NSString *)recordPath duration:(NSInteger)duration
// 1.构造一个 语音消息体
EMChatVoice *chatVoice = [[EMChatVoice alloc] initWithFile:recordPath displayName:@&[语音]&];
EMVoiceMessageBody *voiceBody = [[EMVoiceMessageBody alloc] initWithChatObject:chatVoice];
voiceBody.duration =
[self sendMessage:voiceBody];
发送图片消息
- (void)sendImage:(UIImage *)selectedImage
// 1.构造图片消息体
EMChatImage *orginalChatImg = [[EMChatImage alloc] initWithUIImage:selectedImage displayName:@&[图片]&];
EMImageMessageBody *imgBody = [[EMImageMessageBody alloc]initWithImage:orginalChatImg thumbnailImage:nil];
[self sendMessage:imgBody];
三.把图片显示到cell上//
ChatCell.m
Created by yongkaidong on 16/2/14.
Copyright © 2016年 com.yongkaidong. All rights reserved.
#import &ChatCell.h&
#import &EaseMob.h&
#import &AudioPlayTool.h&
#import &UIImageView+WebCache.h&
@interface ChatCell()
聊天的图片控件(因为懒加载创建所用strong)
@property(nonatomic,strong)UIImageView *chatImageV
@implementation ChatCell
- (UIImageView *)chatImageView
if (!_chatImageView) {
_chatImageView = [[UIImageView alloc] init];
return _chatImageV
-(void)awakeFromNib
// 1.给messageLabel添加手势
self.messageLabel.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(messageLabelTap:)];
[self.messageLabel addGestureRecognizer: tap];
当用户点击messageLabel播放语言
- (void)messageLabelTap:(UIGestureRecognizer *)recognizer
id body = self.message.messageBodies[0];
if ([body isKindOfClass:[EMVoiceMessageBody class]]) {
// 播放语音
BOOL receiver = [self.reuseIdentifier isEqualToString:recivierCell];
[AudioPlayTool playWithMessage:self.message messageLabel:self.messageLabel receiver:receiver];
- (CGFloat)cellHeight
// 1.重新布局子控件(后label的高度已经确定了)
[self layoutIfNeeded];
// 2.返回cell的高度
return self.messageLabel.frame.size.height + 50;
- (void)setMessage:(EMMessage *)message
_message =
// 0.重用cell要移除聊天图片控件
[self.chatImageView removeFromSuperview];
// 1.获取消息体
id body = message.messageBodies[0];
if ([body isKindOfClass:[EMTextMessageBody class]]) { //文本消息
EMTextMessageBody *textBody =
self.messageLabel.text = textBody.
}else if ([body isKindOfClass:[EMVoiceMessageBody class]]){ //语言消息
self.messageLabel.attributedText = [self voiceAttr];
}else if ([body isKindOfClass:[EMImageMessageBody class]]){ //图片消息
[self showImg];
self.messageLabel.text = @&未知类型&;
cell上显示图片
- (void)showImg
// 获取图片消息体
EMImageMessageBody *imgBody = self.message.messageBodies[0];
CGRect thumbnailFrame = (CGRect){0,0,imgBody.thumbnailSize};
// 设置label的尺寸足够显示UIImageView
NSTextAttachment *imgAttach = [[NSTextAttachment alloc] init];
imgAttach.bounds = thumbnailF
NSAttributedString *imgAttri = [NSAttributedString attributedStringWithAttachment:imgAttach];
self.messageLabel.attributedText = imgA
[self.messageLabel addSubview:self.chatImageView];
// 设置图片控件的尺寸为缩略图的尺寸
self.chatImageView.frame = thumbnailF
// 下载图片
NSFileManager *mgr = [NSFileManager defaultManager];
if ([mgr fileExistsAtPath:imgBody.thumbnailLocalPath]) {
//本地路径使用fileURLWithPath
[self.chatImageView sd_setImageWithURL:[NSURL fileURLWithPath:imgBody.thumbnailLocalPath] placeholderImage:nil];
[self.chatImageView sd_setImageWithURL:[NSURL URLWithString:imgBody.thumbnailRemotePath] placeholderImage:nil];
返回语音富文本
- (NSAttributedString *)voiceAttr
// 创建一个可变的富文本
NSMutableAttributedString *voiceAttM = [[NSMutableAttributedString alloc] init];
if ([self.reuseIdentifier isEqualToString:recivierCell]) { //接收方
// 语言图片
UIImage *receiverImg = [UIImage imageNamed:@&chat_receiver_audio_playing_full&];
// 图片附件
NSTextAttachment *imgAttachment = [[NSTextAttachment alloc] init];
imgAttachment.image = receiverI
imgAttachment.bounds = CGRectMake(0, -4, 20, 20);
// 图片富文本
NSAttributedString *imgAtt = [NSAttributedString attributedStringWithAttachment:imgAttachment];
[voiceAttM appendAttributedString:imgAtt];
EMVoiceMessageBody *voiceBody = self.message.messageBodies[0];
NSInteger duration = voiceBody.
NSString *timeStr = [NSString stringWithFormat:@&%ld&,duration];
NSAttributedString *timeAtt = [[NSAttributedString alloc] initWithString:timeStr];
[voiceAttM appendAttributedString:timeAtt];
}else{ //发送方
EMVoiceMessageBody *voiceBody = self.message.messageBodies[0];
NSInteger duration = voiceBody.
NSString *timeStr = [NSString stringWithFormat:@&%ld&,duration];
NSAttributedString *timeAtt = [[NSAttributedString alloc] initWithString:timeStr];
[voiceAttM appendAttributedString:timeAtt];
// 语言图片
UIImage *receiverImg = [UIImage imageNamed:@&chat_sender_audio_playing_full&];
NSTextAttachment *imgAttachment = [[NSTextAttachment alloc] init];
imgAttachment.image = receiverI
imgAttachment.bounds = CGRectMake(0, -4 , 20, 20);
NSAttributedString *imgAtt = [NSAttributedString attributedStringWithAttachment:imgAttachment];
[voiceAttM appendAttributedString:imgAtt];
return [voiceAttM copy];
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:292506次
积分:12879
积分:12879
排名:第800名
原创:994篇
转载:144篇
评论:28条
(21)(60)(76)(27)(57)(96)(80)(33)(14)(40)(83)(83)(82)(106)(36)(26)(41)(82)(44)(26)(19)(24)(7)

我要回帖

更多关于 消息列表 的文章

 

随机推荐