====== EaseUI 使用指南 ======
----
===== 简介 =====
EaseUI 封装了 IM 功能常用的控件(如聊天会话、会话列表、联系人列表)。旨在帮助开发者快速集成环信 SDK。
源码地址:
* [[https://github.com/easemob/easeui_ios/tree/sdk3.x|EaseUI工程]]
* [[https://github.com/easemob/sdkdemoapp3.0_ios/tree/sdk3.x|Demo3.0工程]]
===== 视频教程 =====
以下是EaseUI集成参考视频,您可以通过视频学习如何集成环信SDK。
* OC_EaseUI集成:http://www.imgeek.org/video/39
* Swift_EaseUI集成:http://www.imgeek.org/video/41
===== 快速集成 =====
=== 方法一: ===
pod 'EaseUI', :git => 'https://github.com/easemob/easeui-ios-hyphenate-cocoapods.git'
pod 'EaseUILite', :git =>'https://github.com/easemob/easeui-ios-hyphenate-cocoapods.git'
如果要指定版本,可以在后面添加tag,如
pod 'EaseUI', :git => 'https://github.com/easemob/easeui-ios-hyphenate-cocoapods.git', :tag => ‘3.3.4’
具体tag号和对应sdk版本号,可以从
https://github.com/easemob/easeui-ios-hyphenate-cocoapods/tags查看
**注意:**
EaseUI:对应Hyphenate SDK(sdk包含实时音视频)
EaseUILite:对应HyphenateLite SDK(sdk不包含实时音视频)
Pod集成EaseUI时,会同时通过Pod集成SDK
=== 方法二:===
* 集成 EaseUI 前,首先需要集成环信 iOS SDK,参考:集成文档
* 参考ChatDemo3.0 导入的方式,直接将EaseUI拖入已经集成SDK的项目中
**注意:**
* 添加的SDK要和EaseUI是同时下载的(目的是版本一致)。
* 如果使用Lite版本SDK,并用拖动的方式添加EaseUI, 需要在 ''Build Settings'' > ''GCC_PREPROCESSOR_DEFINITIONS'' 中添加 ''ENABLE_LITE=1'' (等号左右不能有空格)
**easeui中包含了拍照,发语音,发图片,发位置的功能,使用了录音,摄像头,相册,地理位置的权限。需要在您项目的info.plist中添加对应权限。**
===== 初始化 =====
第 1 步:引入相关头文件 #import "EaseUI.h"。
第 2 步:在工程的 AppDelegate 中的以下方法中,调用 EaseUI 对应方法。(注: 此方法不需要重复调用)
[[EaseSDKHelper shareHelper] hyphenateApplication:application
didFinishLaunchingWithOptions:launchOptions
appkey:appkey
apnsCertName:apnsCertName
otherConfig:@{kSDKConfigEnableConsoleLogger:[NSNumber numberWithBool:YES]}];
===== 聊天会话 =====
创建聊天会话、传递用户或群 ID 和会话类型(EMConversationType)。
EaseMessageViewController *chatController = [[EaseMessageViewController alloc] initWithConversationChatter:@"8001" conversationType:EMConversationTypeChat];
===== 聊天页面刷新 =====
EaseRefreshTableViewController提供了列表上拉加载、下拉刷新(加载)功能的UIViewController,其中已添加控件UITableView,默认未开启上拉加载、下来刷新(加载)的功能
==== 实现上拉加载功能 ====
继承自**EaseRefreshTableViewController**的子类,开启上拉加载需要设置showRefreshFooter为YES,并重写父类方法**- (void)tableViewDidTriggerFooterRefresh;**,如下:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.showRefreshFooter = YES;
}
- (void)tableViewDidTriggerFooterRefresh {
//子类需要重写此方法
}
==== 实现下拉加载(刷新)功能 ====
继承自**EaseRefreshTableViewController**的子类,开启下拉加载(刷新)需要设置showRefreshHeader为YES,并重写父类方法**- (void)tableViewDidTriggerHeaderRefresh;**,如下:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.showRefreshHeader = YES;
}
- (void)tableViewDidTriggerHeaderRefresh {
//子类需要重写此方法
}
===== 聊天会话功能扩展 =====
EaseUI 提供现成的聊天会话 ViewController,可以通过继承 EaseMessageViewController 方式(参考 ChatDemo-UI3.0 中 ChatViewController)实现对聊天会话的扩展。
也可以直接使用 EaseMessageViewController,通过 EaseMessageViewControllerDelegate 和 EaseMessageViewControllerDataSource 两个协议实现对 EaseMessageViewController 的扩展。
==== 实现自定义聊天样式 ====
EaseMessageViewControllerDelegate
获取自定义消息 cell,根据 messageModel,用户自己判断是否显示自定义消息 cell。如果返回 nil 会显示默认;如果返回 cell 会显示用户自定义消息cell。
/*!
@method
@brief 获取消息自定义cell
@discussion 用户根据messageModel判断是否显示自定义cell。返回nil显示默认cell,否则显示用户自定义cell
@param tableView 当前消息视图的tableView
@param messageModel 消息模型
@result 返回用户自定义cell
*/
- (UITableViewCell *)messageViewController:(UITableView *)tableView
cellForMessageModel:(id)messageModel;
/*!
@method
@brief 获取消息cell高度
@discussion 用户根据messageModel判断,是否自定义显示cell的高度
@param viewController 当前消息视图
@param messageModel 消息模型
@param cellWidth 视图宽度
@result 返回用户自定义cell
*/
- (CGFloat)messageViewController:(EaseMessageViewController *)viewController
heightForMessageModel:(id)messageModel
withCellWidth:(CGFloat)cellWidth;
//具体创建自定义Cell的样例:
- (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id)model
{
//样例为如果消息是文本消息显示用户自定义cell
if (model.bodyType == eMessageBodyType_Text) {
NSString *CellIdentifier = [CustomMessageCell cellIdentifierWithModel:model];
//CustomMessageCell为用户自定义cell,继承了EaseBaseMessageCell
CustomMessageCell *cell = (CustomMessageCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier model:model];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.model = model;
return cell;
}
return nil;
}
- (CGFloat)messageViewController:(EaseMessageViewController *)viewController
heightForMessageModel:(id)messageModel
withCellWidth:(CGFloat)cellWidth
{
//样例为如果消息是文本消息使用用户自定义cell的高度
if (messageModel.bodyType == EMMessageBodyTypeText) {
//CustomMessageCell为用户自定义cell,继承了EaseBaseMessageCell
return [CustomMessageCell cellHeightWithModel:messageModel];
}
return 0.f;
}
通过自定义cell展示动态表情的效果图:
{{:start:300iosclientintegration:ios_easeui_chatview_customcell.png?200|通过自定义cell展示动态表情的效果图}}
选中消息的回调
/*!
@method
@brief 选中消息的回调
@discussion 用户根据messageModel判断,是否自定义处理消息选中时间。返回YES为自定义处理,返回NO为默认处理
@param viewController 当前消息视图
@param messageModel 消息模型
@result 是否采用自定义处理
*/
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
didSelectMessageModel:(id)messageModel;
//选中消息回调的样例:
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
didSelectMessageModel:(id)messageModel
{
BOOL flag = NO;
//样例为如果消息是文件消息用户自定义处理选中逻辑
switch (messageModel.bodyType) {
case EMMessageBodyTypeImage:
case EMMessageBodyTypeLocation:
case EMMessageBodyTypeVideo:
case EMMessageBodyTypeVoice:
break;
case EMMessageBodyTypeFile:
{
flag = YES;
NSLog(@"用户自定义实现");
}
break;
default:
break;
}
return flag;
}
用户选中头像的回调
/*!
@method
@brief 点击消息头像
@discussion 获取用户点击头像回调
@param viewController 当前消息视图
@param messageModel 消息模型
@result
*/
- (void)messageViewController:(EaseMessageViewController *)viewController
didSelectAvatarMessageModel:(id)messageModel;
//获取用户点击头像回调的样例:
- (void)messageViewController:(EaseMessageViewController *)viewController
didSelectAvatarMessageModel:(id)messageModel
{
//UserProfileViewController用户自定义的个人信息视图
//样例的逻辑是选中消息头像后,进入该消息发送者的个人信息
UserProfileViewController *userprofile = [[UserProfileViewController alloc] initWithUsername:messageModel.message.from];
[self.navigationController pushViewController:userprofile animated:YES];
}
录音按钮状态的回调
/*!
@method
@brief 底部录音功能按钮状态回调
@discussion 获取底部录音功能按钮状态回调,根据EaseRecordViewType,用户自定义处理UI的逻辑
@param viewController 当前消息视图
@param recordView 录音视图
@param type 录音按钮当前状态
@result
*/
- (void)messageViewController:(EaseMessageViewController *)viewController
didSelectRecordView:(UIView *)recordView
withEvenType:(EaseRecordViewType)type;
//录音按钮状态的回调样例:
- (void)messageViewController:(EaseMessageViewController *)viewController
didSelectRecordView:(UIView *)recordView
withEvenType:(EaseRecordViewType)type
{
/*
EaseRecordViewTypeTouchDown,//录音按钮按下
EaseRecordViewTypeTouchUpInside,//手指在录音按钮内部时离开
EaseRecordViewTypeTouchUpOutside,//手指在录音按钮外部时离开
EaseRecordViewTypeDragInside,//手指移动到录音按钮内部
EaseRecordViewTypeDragOutside,//手指移动到录音按钮外部
*/
//根据type类型,用户自定义处理UI的逻辑
switch (type) {
case EaseRecordViewTypeTouchDown:
{
if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
[(EaseRecordView *)self.recordView recordButtonTouchDown];
}
}
break;
case EaseRecordViewTypeTouchUpInside:
{
if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
[(EaseRecordView *)self.recordView recordButtonTouchUpInside];
}
[self.recordView removeFromSuperview];
}
break;
case EaseRecordViewTypeTouchUpOutside:
{
if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
[(EaseRecordView *)self.recordView recordButtonTouchUpOutside];
}
[self.recordView removeFromSuperview];
}
break;
case EaseRecordViewTypeDragInside:
{
if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
[(EaseRecordView *)self.recordView recordButtonDragInside];
}
}
break;
case EaseRecordViewTypeDragOutside:
{
if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
[(EaseRecordView *)self.recordView recordButtonDragOutside];
}
}
break;
default:
break;
}
}
EaseMessageViewControllerDataSource
用户判断消息是否允许长按,返回布尔值;如果用户允许长按,此方法为通知用户触发长按手势,返回布尔值,如果返回 NO 默认方式处理,返回 YES 采用用户自定义的处理方式。
/*!
@method
@brief 是否允许长按
@discussion 获取是否允许长按的回调,默认是NO
@param viewController 当前消息视图
@param indexPath 长按消息对应的indexPath
@result
*/
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
canLongPressRowAtIndexPath:(NSIndexPath *)indexPath;
/*!
@method
@brief 触发长按手势
@discussion 获取触发长按手势的回调,默认是NO
@param viewController 当前消息视图
@param indexPath 长按消息对应的indexPath
@result
*/
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
didLongPressRowAtIndexPath:(NSIndexPath *)indexPath;
//长按收拾回调样例:
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
canLongPressRowAtIndexPath:(NSIndexPath *)indexPath
{
//样例给出的逻辑是所有cell都允许长按
return YES;
}
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
didLongPressRowAtIndexPath:(NSIndexPath *)indexPath
{
//样例给出的逻辑是长按cell之后显示menu视图
id object = [self.dataArray objectAtIndex:indexPath.row];
if (![object isKindOfClass:[NSString class]]) {
EaseMessageCell *cell = (EaseMessageCell *)[self.tableView cellForRowAtIndexPath:indexPath];
[cell becomeFirstResponder];
self.menuIndexPath = indexPath;
[self _showMenuViewController:cell.bubbleView andIndexPath:indexPath messageType:cell.model.bodyType];
}
return YES;
}
Demo3.0实现的消息长按效果演示:
{{:start:300iosclientintegration:ios_easeui_chatview_menu.png?200|Demo3.0实现的消息长按效果演示}}
将EMMessage类型转换为符合协议的类型,设置用户信息,消息显示用户昵称和头像。
/*!
@method
@brief 将EMMessage类型转换为符合协议的类型
@discussion 将EMMessage类型转换为符合协议的类型,设置用户信息,消息显示用户昵称和头像
@param viewController 当前消息视图
@param EMMessage 聊天消息对象类型
@result 返回协议的类型
*/
- (id)messageViewController:(EaseMessageViewController *)viewController
modelForMessage:(EMMessage *)message;
//具体样例:
- (id)messageViewController:(EaseMessageViewController *)viewController
modelForMessage:(EMMessage *)message
{
//用户可以根据自己的用户体系,根据message设置用户昵称和头像
id model = nil;
model = [[EaseMessageModel alloc] initWithMessage:message];
model.avatarImage = [UIImage imageNamed:@"EaseUIResource.bundle/user"];//默认头像
model.avatarURLPath = @"";//头像网络地址
model.nickname = @"昵称";//用户昵称
return model;
}
聊天会话页面头像和昵称的效果演示:
{{:start:300iosclientintegration:ios_easeui_chatview.png?200|聊天会话页面头像和昵称的效果演示}}
==== 聊天会话样式自定义 ====
聊天样式的自定义需要在 EaseMessageViewController 中 viewDidload 结束前设置。\\
@property中带有UI_APPEARANCE_SELECTOR,都可以通过set的形式设置样式,具体可以参考EaseBaseMessageCell.h,EaseMessageCell.h\\
=== 发送气泡图片设置 ===
[[EaseBaseMessageCell appearance] setSendBubbleBackgroundImage:[[UIImage imageNamed:@"chat_sender_bg"] stretchableImageWithLeftCapWidth:5 topCapHeight:35]];//设置发送气泡
[[EaseBaseMessageCell appearance] setRecvBubbleBackgroundImage:[[UIImage imageNamed:@"chat_receiver_bg"] stretchableImageWithLeftCapWidth:35 topCapHeight:35]];//设置接收气泡
=== 头像设置 ===
[[EaseBaseMessageCell appearance] setAvatarSize:40.f];//设置头像大小
[[EaseBaseMessageCell appearance] setAvatarCornerRadius:20.f];//设置头像圆角
=== 消息字体颜色设置 ===
[[EaseMessageCell appearance] setMessageTextFont:[UIFont systemFontOfSize:15]];//消息显示字体
[[EaseMessageCell appearance] setMessageTextColor:[UIColor blackColor]];//消息显示颜色
[[EaseMessageCell appearance] setMessageLocationFont:[UIFont systemFontOfSize:12]];//位置消息显示字体
[[EaseMessageCell appearance] setMessageLocationColor:[UIColor whiteColor]];//位置消息显示颜色
=== 语音消息图片样式设置 ===
[[EaseBaseMessageCell appearance] setSendMessageVoiceAnimationImages:@[[UIImage imageNamed:@"EaseUIResource.bundle/chat_sender_audio_playing_full"], [UIImage imageNamed:@"EaseUIResource.bundle/chat_sender_audio_playing_000"], [UIImage imageNamed:@"EaseUIResource.bundle/chat_sender_audio_playing_001"], [UIImage imageNamed:@"EaseUIResource.bundle/chat_sender_audio_playing_002"], [UIImage imageNamed:@"EaseUIResource.bundle/chat_sender_audio_playing_003"]]];//发送者语音消息播放图片
[[EaseBaseMessageCell appearance] setRecvMessageVoiceAnimationImages:@[[UIImage imageNamed:@"EaseUIResource.bundle/chat_receiver_audio_playing_full"],[UIImage imageNamed:@"EaseUIResource.bundle/chat_receiver_audio_playing000"], [UIImage imageNamed:@"EaseUIResource.bundle/chat_receiver_audio_playing001"], [UIImage imageNamed:@"EaseUIResource.bundle/chat_receiver_audio_playing002"], [UIImage imageNamed:@"EaseUIResource.bundle/chat_receiver_audio_playing003"]]];//接收者语音消息播放图片
==== 聊天会话输入框自定义 ====
继承EaseMessageViewController,或者EaseMessageViewController的实例调用以下方法设置底部输入框
CustomerInputView *inputView = [[CustomerInputView alloc] init];//CustomerInputView用户自定义底部输入框
[self setChatToolbar:inputView];
实现默认底部输入框delegate
@interface CustomerInputView : UIView
@property (weak, nonatomic) id delegate;
@end
=== 自定义输入框发送消息 ===
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
if ([text isEqualToString:@"\n"]){
if(self.delegate && [self.delegate respondsToSelector:@selector(didSendText:)]) {
[self.delegate didSendText:self.textView.text];
}
self.textView.text = @"";
self.placeholderLabel.text = @"说点什么吧...";
return NO;
}
return YES;
}
=== 自定义输入框高度变化 ===
//这是一个举例,初始化输入框的时候注册监听键盘高度变化
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:)name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:)name:UIKeyboardWillHideNotification object:nil];
- (void)keyboardWillShow:(NSNotification *)aNotification{
//获取键盘的高度
NSValue *aValue = [[aNotification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardRect = [aValue CGRectValue];
if (keyboardRect.size.height > self.keyboardHeight) {
self.keyboardHeight = keyboardRect.size.height;
}
self.frame = CGRectMake(0, _originY - self.keyboardHeight - 64, App_Width, self.inputH + self.keyboardHeight);
if (self.delegate && [self.delegate respondsToSelector:@selector(chatToolbarDidChangeFrameToHeight:)]) {
[self.delegate chatToolbarDidChangeFrameToHeight:self.frame.size.height];
}
}
- (void)keyboardWillHide:(NSNotification *)aNotification{
self.frame = CGRectMake(0, _originY - 64, App_Width, self.inputH) ;
if (self.delegate && [self.delegate respondsToSelector:@selector(chatToolbarDidChangeFrameToHeight:)]) {
[self.delegate chatToolbarDidChangeFrameToHeight:self.frame.size.height];
}
}
==== 聊天会话底部菜单自定义 ====
**EaseChatBarMoreView**为自定义的功能菜单选择视图,目前已添加的功能有:\\
/*!
@method
@brief 新增一个新的功能按钮
@discussion
@param image 按钮图片
@param highLightedImage 高亮图片
@param title 按钮标题
@result
*/
- (void)insertItemWithImage:(UIImage*)image
highlightedImage:(UIImage*)highLightedImage
title:(NSString*)title;
/*!
@method
@brief 修改功能按钮图片
@discussion
@param image 按钮图片
@param highLightedImage 高亮图片
@param title 按钮标题
@param index 按钮索引
@result
*/
- (void)updateItemWithImage:(UIImage*)image
highlightedImage:(UIImage*)highLightedImage
title:(NSString*)title
atIndex:(NSInteger)index;
/*!
@method
@brief 根据索引删除功能按钮
@discussion
@param index 按钮索引
@result
*/
- (void)removeItematIndex:(NSInteger)index;
各个选项的功能需要ViewController实现EaseChatBarMoreViewDelegate协议中的回调方法来编写或调整.
===== 消息发送 =====
EaseSDKHelper 封装了发送消息的方法。
具体发送消息样例:
/*
EMChatTypeChat 单聊消息
EMChatTypeGroupChat 群聊消息
EMChatTypeChatRoom 聊天室消息
*/
//发送文字消息
EMMessage *message = [EaseSDKHelper sendTextMessage:@"要发送的消息"
to:@"6001"//接收方
messageType:EMChatTypeChat//消息类型
messageExt:nil]; //扩展信息
//发送位置消息
EMMessage *message = [EaseSDKHelper sendLocationMessageWithLatitude:35.1//经度
longitude:35.1//纬度
address:"地址"
to:@"6001"//接收方
messageType:EMChatTypeChat//消息类型
messageExt:nil];//扩展信息
//发送图片消息
EMMessage *message = [EaseSDKHelper sendImageMessageWithImageData:imageData//发送的图片数据NSData
to:@"6001"//接收方
messageType:EMChatTypeChat//消息类型
messageExt:nil];//扩展信息
//发送音频消息
EMMessage *message = [EaseSDKHelper sendVoiceMessageWithLocalPath:localPath//音频本地地址
duration:duration//语音的时长,单位是秒
to:@"6001"//接收方
messageType:EMChatTypeChat//消息类型
messageExt:nil];//扩展信息
//发送视频文件消息
EMMessage *message = [EaseSDKHelper sendVideoMessageWithURL:url//发送的视频地址
to:@"6001"//接收方
messageType:EMChatTypeChat//消息类型
messageExt:nil];//扩展信息
//发送构造成功的消息
[[EMClient sharedClient].chatManager asyncSendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {
}];
===== 会话列表 =====
==== 会话列表初始化 ====
EaseConversationListViewController *chatListVC = [[EaseConversationListViewController alloc] init];
==== 会话列表下拉刷新 ====
需要继承**EaseConversationListViewController**的子类,在viewDidLoad中加入
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.showRefreshHeader = YES;
//首次进入加载数据
[self tableViewDidTriggerHeaderRefresh];
}
==== 会话列表扩展 ====
EaseConversationListViewControllerDataSource
用户根据 conversationModel 实现,实现自定义会话中最后一条消息文案的显示内容。
/*!
@method
@brief 获取最后一条消息显示的内容
@discussion 用户根据conversationModel实现,实现自定义会话中最后一条消息文案的显示内容
@param conversationListViewController 当前会话列表视图
@param IConversationModel 会话模型
@result 返回用户最后一条消息显示的内容
*/
- (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
latestMessageTitleForConversationModel:(id)conversationModel;
/*!
@method
@brief 获取最后一条消息显示的时间
@discussion 用户可以根据conversationModel,自定义实现会话列表中时间文案的显示内容
@param conversationListViewController 当前会话列表视图
@param IConversationModel 会话模型
@result 返回用户最后一条消息时间的显示文案
*/
- (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
latestMessageTimeForConversationModel:(id)conversationModel;
//最后一条消息展示内容样例
- (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
latestMessageTitleForConversationModel:(id)conversationModel
{
NSString *latestMessageTitle = @"";
EMMessage *lastMessage = [conversationModel.conversation latestMessage];
if (lastMessage) {
EMMessageBody *messageBody = lastMessage.body;
switch (messageBody.type) {
case EMMessageBodyTypeImage:{
latestMessageTitle = NSLocalizedString(@"message.image1", @"[image]");
} break;
case EMMessageBodyTypeText:{
// 表情映射。
NSString *didReceiveText = [EaseConvertToCommonEmoticonsHelper
convertToSystemEmoticons:((EMTextMessageBody *)messageBody).text];
latestMessageTitle = didReceiveText;
if ([lastMessage.ext objectForKey:MESSAGE_ATTR_IS_BIG_EXPRESSION]) {
latestMessageTitle = @"[动画表情]";
}
} break;
case EMMessageBodyTypeVoice:{
latestMessageTitle = NSLocalizedString(@"message.voice1", @"[voice]");
} break;
case EMMessageBodyTypeLocation: {
latestMessageTitle = NSLocalizedString(@"message.location1", @"[location]");
} break;
case EMMessageBodyTypeVideo: {
latestMessageTitle = NSLocalizedString(@"message.video1", @"[video]");
} break;
case EMMessageBodyTypeFile: {
latestMessageTitle = NSLocalizedString(@"message.file1", @"[file]");
} break;
default: {
} break;
}
}
return latestMessageTitle;
}
//最后一条消息展示时间样例
- (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
latestMessageTimeForConversationModel:(id)conversationModel
{
NSString *latestMessageTime = @"";
EMMessage *lastMessage = [conversationModel.conversation latestMessage];;
if (lastMessage) {
latestMessageTime = [NSDate formattedTimeFromTimeInterval:lastMessage.timestamp];
}
return latestMessageTime;
}
会话列表最后一条消息和时间显示的效果演示:
{{:start:300iosclientintegration:ios_easeui_conversation.png?200|会话列表最后一条消息和时间显示的效果演示}}
EaseConversationListViewControllerDelegate
点击会话列表用户可以根据 conversationModel 自定义处理逻辑。
/*!
@method
@brief 获取点击会话列表的回调
@discussion 获取点击会话列表的回调后,点击会话列表用户可以根据conversationModel自定义处理逻辑
@param conversationListViewController 当前会话列表视图
@param IConversationModel 会话模型
@result
*/
- (void)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
didSelectConversationModel:(id)conversationModel;
//会话列表点击的回调样例
- (void)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
didSelectConversationModel:(id)conversationModel
{
//样例展示为根据conversationModel,进入不同的会话ViewController
if (conversationModel) {
EMConversation *conversation = conversationModel.conversation;
if (conversation) {
if ([[RobotManager sharedInstance] isRobotWithUsername:conversation.conversationId]) {
RobotChatViewController *chatController = [[RobotChatViewController alloc] initWithConversationChatter:conversation.conversationId conversationType:conversation.type];
chatController.title = [[RobotManager sharedInstance] getRobotNickWithUsername:conversation.conversationId];
[self.navigationController pushViewController:chatController animated:YES];
} else {
ChatViewController *chatController = [[ChatViewController alloc] initWithConversationChatter:conversation.conversationId conversationType:conversation.type];
chatController.title = conversationModel.title;
[self.navigationController pushViewController:chatController animated:YES];
}
}
[[NSNotificationCenter defaultCenter] postNotificationName:@"setupUnreadMessageCount" object:nil];
[self.tableView reloadData];
}
}
===== 联系人列表 =====
==== 联系人列表初始化 ====
EaseUsersListViewController *listViewController = [[EaseUsersListViewController alloc] init];
==== 联系人列表下拉刷新 ====
需要继承**EaseUsersListViewController**的子类,在viewDidLoad中加入
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.showRefreshHeader = YES;
}
==== 联系人列表扩展 ====
需要实现 EMUserListViewControllerDataSource。
根据 buddy 获取用户自定信息,联系人列表里展示昵称和头像。
/*!
@method
@brief 获取用户模型
@discussion 根据buddy获取用户自定信息,联系人列表里展示昵称和头像
@param userListViewController 当前联系人视图
@param buddy 好友的信息描述类
@result 返回用户模型
*/
- (id)userListViewController:(EaseUsersListViewController *)userListViewController
modelForBuddy:(NSString *)buddy;
//联系人列表扩展样例
- (id)userListViewController:(EaseUsersListViewController *)userListViewController
modelForBuddy:(NSString *)buddy
{
//用户可以根据自己的用户体系,根据buddy设置用户昵称和头像
id model = nil;
model = [[EaseUserModel alloc] initWithBuddy:buddy];
model.avatarURLPath = @"";//头像网络地址
model.nickname = @"昵称";//用户昵称
return model;
}
联系人列表头像和昵称的效果演示:
{{:start:300iosclientintegration:ios_easeui_contact.png?200|联系人列表头像和昵称的效果演示}}
===== EaseUI中使用的第三方库 =====
* MBProgressHUD
* MJRefresh
* MWPhotoBrowser
* SDWebImage
* DACircularProgressView
==== EaseUI中第三方库冲突问题 ====
目前推荐Pod的方式集成EaseUI。如果集成了EaseUI,而且上述第三方依赖在开发者的代码中也有引用,会造成冲突,无法编译,针对此问题有如下两种场景:
* 开发者使用的第三方依赖也是通过pod方式集成,这样pod只会安装一份,不会重复安装多个版本。如果是依赖版本不兼容,例如开发者依赖了'''MBProgressHUD', '~> 1.0.0' '',而EaseUI通过MWPhotoBrowser间接依赖了'''MBProgressHUD', '~> 0.9' '',这样会导致pod install失败,开发者可以改变''MBProgressHUD''的依赖版本。EaseUI也会在后续版本中尽量减少使用第三方依赖。
* 如果是手动导入了上述第三方库,建议直接删除手动导入的部分,避免冲突的产生,如果EaseUI使用第三方库的版本不能满足开发者的需求,开发者也可以手动将第三方库进行重命名,保证兼容(手动方式集成EaseUI也可以参考此解决方案)。
----
上一页:[[im:300iosclientintegration:apnscontent|APNs 内容解析]]
下一页:[[im:300iosclientintegration:80appledoc|iOS SDK API Doc]]