最近一直在赶项目,项目暂时告一段落。新的项目用到了环信。以前没有接触过,在这么做一个总结。其实环信用起来还是比较方便,比较简单。希望可以帮助看到的朋友们。
第一步集成环信
使用cocoapod还是比较方便的一种方式。我的项目是在EaseUI的基础上做的修改,所以还需要基础EaseUI
pod 'HyphenateLite'
pod 'EaseUI', :git => 'https://github.com/easemob/easeui-ios-hyphenate-cocoapods.git'
pod install
这些就比较简单了,文档上都有介绍,详情查看官方文档。
第二步基础功能实现
注册
注册模式分为开放注册和授权注册。
只有开放注册时,才可以客户端注册。开放注册是为了测试使用,正式环境中不推荐使用该方式注册环信账号。
授权注册的流程应该是您服务器通过环信提供的 REST API 注册,之后保存到您的服务器或返回给客户端。
登录
所以一般的APP中,项目是不需要考虑注册的,注册是后台的事情。我们需要做的是:
客户端用户在登录APP时,我们从后台拿到环信的注册账号和密码,保证在本地,在项目初始化
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中配置环信账号完成后。实现登录方法。
环信有登录方法和自动登录,所以一般是自动登录,如何自动登录失败在用环信方法实现登录。
退出登录
退出登录是客户端登录登录的时候,我们操作同时退出环信的登录。
调用主动退出登录的方法退出登录
EMError *error = [[EMClient sharedClient] logout:YES];if (!error) {
NSLog(@"退出成功");
}
第三步单聊的实现
聊天的功能是在EaseUI的基础上做的。
单聊页面
初始化
代码:
用于初始化页面
EaseMessageViewController *chatController = [[EaseMessageViewController alloc] initWithConversationChatter:@"8001" conversationType:EMConversationTypeChat];
~~~~~~~~~~~~~~~~~单聊通过扩展修改头像和昵称~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
继承EaseMessageViewController实现自己的Controller,此时如果你不做任何操作,也是可以实现聊天的。这就是你的单聊聊天界面。
单聊页面一般实现的功能:
点击对方的头像,可以查看对方的一些用户信息。
点击自定义消息,可以查看消息详情。相当于跳到一个界面。
聊天回话底部菜单自定义。
自定义聊天样式。
现在先说一下怎么实现修改头像和昵称。
我使用的方法是通过扩展实现,自定义头像和昵称。就是在每次发送消息的时候,在扩展体中,增加字段。
实例:
接下来就是修改EaseMessageViewController了
以下的方法都需要修改
- (void)sendTextMessage:(NSString *)text;
- (void)sendImageMessage:(UIImage *)image;
- (void)sendLocationMessageLatitude:(double)latitude
longitude:(double)longitude
andAddress:(NSString *)address;
- (void)sendVoiceMessageWithLocalPath:(NSString *)localPath
duration:(NSInteger)duration;
- (void)sendVideoMessageWithURL:(NSURL *)url;
- (void)sendFileMessageWith:(EMMessage *)message;
修改如下:
自定义扩展
你需要在所以得发送消息的方法里添加扩展字段。这样你每条消息都带有扩展,可以拿到头像和昵称。
获得扩展,更改头像和昵称
进入EaseUI的EaseBaseMessageCell.m中找到setModel方法
到此基本的昵称头像已经完成。但是需要注意的所以我们在扩展的字典发的头像和昵称都是自己的头像和昵称。
在此处遇到的bug~
如果对方一直不会你的消息你是无法拿到对方的昵称和头像,也无法设置contrller的title为用户的头像。为了解决此问题。我在扩展中太添加了一个sendUserName 和sendUserHead字段,同时在初始化EaseMessageViewController的方法中把拿到的扩展放到会话的扩展中。
- (instancetype)initWithConversationChatter:(NSString *)conversationChatter
conversationType:(EMConversationType)conversationType
{
if ([conversationChatter length] == 0) {
return nil;
}
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
_conversation = [[EMClient sharedClient].chatManager getConversation:conversationChatter type:conversationType createIfNotExist:YES];
//将消息的扩展内容绑定到回话
EMMessage *message = _conversation.latestMessage;
NSDictionary *dict = message.ext;
_conversation.ext = dict;
_messageCountOfPage = 10;
_timeCellHeight = 30;
_deleteConversationIfNull = YES;
_scrollToBottomWhenAppear = YES;
_messsagesSource = [NSMutableArray array];
[_conversation markAllMessagesAsRead:nil];
}
return self;
}
同时在发送消息的是判断是否有此字段如果没有就不需要赋值,如果有就从会话中拿到赋值。
取值
做的判断是先拿最后一条收到的message的扩展,如何没有就拿最后一条数据的扩展,如何扩展中有这个字段就赋值,如何没有就去回话的扩展中取值。
这样昵称头像的修改就算完成。
实现代理方法
点击用户头像实现跳转的方法:
//用户选中头像的回调- (void)messageViewController:(EaseMessageViewController *)viewController didSelectAvatarMessageModel:(id)messageModel{}
点击cell实现的方法
/*! @method @brief 选中消息 @discussion 选中消息的回调,用户可以自定义处理 @param viewController 当前消息视图 @param messageModel 消息模型 */
- (BOOL)messageViewController:(EaseMessageViewController *)viewController didSelectMessageModel:(id)messageModel
{}
到此就算实现了基本的单聊
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~自定义聊天cell~~~~~~~~~~~~~~~~~~~~~~~~~~~
第一步:继承 EaseBaseMessageCell
第二步初始化控件
第三步重写cell的初始化方法添加控件
添加子控件并且赋值
方法重写
到此自定义cell完成
接下来需要在EaseMessageViewContrller实现delegate方法
根据接受model的类型家长cell
-(UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id)messageModel{}
获取cell的高度
/*! @method @brief 获取消息cell高度 @discussion 用户根据messageModel判断,是否自定义显示cell的高度 @param viewController 当前消息视图 @param messageModel 消息模型 @param cellWidth 视图宽度 @result 返回用户自定义cell */
- (CGFloat)messageViewController:(EaseMessageViewController *)viewController heightForMessageModel:(id)messageModel
withCellWidth:(CGFloat)cellWidth
{
if (messageModel.bodyType == EMMessageBodyTypeText) {
NSDictionary *ext = messageModel.message.ext;
NSString *dataTypeStr = [ext valueForKey:@"dataType"];
int dataType = dataTypeStr.intValue;
if (dataType == 102) {
return [ZGChatHouseCell cellHeightWithModel:messageModel];
}
}
return 0.f;
}
自定义cell完成
会话列表
需要继承EaseConversationListViewController
然后在viewDidLoad中
self.showRefreshHeader = YES;
//首次进入加载数据
[self tableViewDidTriggerHeaderRefresh];
这个比较简单看看官网的文档就可以
我在这里只是介绍一下头像和昵称
这个逻辑很单聊界面的是一样的
#pragma mark - EaseConversationListViewControllerDataSource/*! @method @brief 构建实现协议IConversationModel的model @discussion 用户可以创建实现协议IConversationModel的自定义conversationModel对象,按照业务需要设置属性值 @param conversationListViewController 当前会话列表视图 @param conversation 会话对象 @result 返回实现协议IConversationModel的model对象 */
- (id)conversationListViewController:(EaseConversationListViewController *)conversationListViewController modelForConversation:(EMConversation *)conversation
{
EaseConversationModel *model = [[EaseConversationModel alloc] initWithConversation:conversation];
if (model.conversation.type == EMConversationTypeChat) {
EMMessage * msg = conversation.lastReceivedMessage;
NSString *pic = nil;
NSString *nickNames;
if (msg) {
nickNames = [msg.ext valueForKey:@"userName"];
pic = [msg.ext valueForKey:@"headImg"];
model.title = nickNames;
model.avatarURLPath = pic;
}else{
EMMessage * resMes = conversation.latestMessage;
if (isEmpty([resMes.ext valueForKey:@"sendUserName"])) {
NSDictionary * conExt = conversation.ext;
nickNames = [conExt valueForKey:@"sendUserName"];
pic = [conExt valueForKey:@"sendHeadImg"];
model.title = nickNames;
model.avatarURLPath = pic;
}else{
nickNames = [resMes.ext valueForKey:@"sendUserName"];
pic = [resMes.ext valueForKey:@"sendHeadImg"];
model.title = nickNames;
model.avatarURLPath = pic;
}
}
}
return model;
}
OK就简单介绍这些吧~有时间在介绍一下环信的消息推送。
写的比较乱~希望可以帮助到需要的人。