环信SDK3.2.3和EaseUI消息列表和聊天的简单实现

来源:互联网 发布:苏州软件测试培训 编辑:程序博客网 时间:2024/05/23 01:23

因为项目以前的环信,是要用到环信的EaseUI的。所以集成的时候,只能手动导入(原因下面会说到),这里介绍的也是手动导入。

从环信官网上下来的包如图


环信开发包
然后目录解释环信文档上也有解释

从官网上下载下来的包中分为如下五部分:

环信 iOS HyphenateSDK 开发使用(不包含实时通话功能)

环信 iOS HyphenateFullSDK 开发使用(包含实时通话功能)

环信 iOS doc SDK 相关API文档

环信 iOS ChatUIDemo3.0 工程源码

环信 iOS EaseUI 工程源码

环信 iOS chatdemo-ui-3.x.x.ipa 打包的 spa

上面提过,项目中要用EaseUI,所以别看环信给了你两个选择,可以导入一个不包含实时通话的,可以小一点。但是环信封装的EaseUI里面,引用的库是包含实时通话的HyphenateFullSDK,所以 ,只能导入HyphenateFullSDK库。。。蛋疼。

这时候有小伙伴就说,那我可以cocopod导入HyphenateFullSDK库,然后手动导入EaseUI啊。


本人试过,结果就是,EaseUI内部会报错方法找不到,然后你对比一下cocopod导入的HyphenateFullSDK库比手动导入的HyphenateFullSDK库会少几个方法。。。少的就是那几个报错的方法。。。

本人pod search了一下 看了一下版本 Hyphenate 的版本是3.1.5,但是下载下来的是3.2.3。。。我有点方了。。。

然后想了一种方法,手动导入Hyphenate 但是pod EaseUI。但是有朋友说,EaseUI最好手动导入,因为有可能你会修改EaseUI,所以不建议pod。


好吧,我认命了,按环信文档手动导入Hyphenate和EaseUI,并添加系统依赖库。

然后,编译失败。。。

你可以看一下错误,基本就是找不到UIKit,

解决方法:在pch文件中加入UIKit,注意,OBJC千万不要忘。

#ifdef __OBJC__#import<UIKit/UIKit.h>#endif

然后再编译,又失败。。。

看了一下,跟项目中本身的MJ库冲突,没办法,只能删了。

然后再编译,又错。。。这次是我的错,环信不支持Bitcode,记得Bitcode为NO

然后在编译,过了,恩,Nice。

运行,然后崩了。。。


卧槽,我只是导入啊,代码还没开始写那。难道是我打开的方式不对?

试了几次,发现连Appdelegate都没进去。。。


崩溃的地方和打印
然后上网找了一圈,看到了一位大哥说的,说出现Reason: image not found错误,把Hyphenate.Framework库要改成Optional就好了,如图下。



示例图
改完以后,果然好了,当时心里各种感觉大哥啊。然后就开始写代码,但是出现一个问题,登录的block一直不回调,但是也没有错误。环信也没有日志。。。我感觉我貌似被坑了。。。

对照了一下环信的示例demo,人家的Hyphenate.Framework也不是Optional啊。但是在Build Phases里多了一行


环信demo的Build Phases
尼玛,坑爹啊,多的这个为毛文档里没有。

加上了这个,果然好了。

那位大哥,我很好奇,你是怎么用那个方法解决的。。。

对于SDK的初始化,登录,注册什么的 就不说了,自己看文档去吧。

这里主要说下基于EaseUI,实现消息列表页和聊天界面


环信默认的聊天界面
因为环信提供的聊天界面和消息列表界面,是没有昵称和头像的,一般的用户的图片和用户名,都是存在自己服务器的,那怎么把聊天界面中的头像和用户名换成自己的服务器上的数据?

方法一:从APP服务器获取昵称和头像昵称和头像的获取:当收到一条消息(群消息)时,得到发送者的用户ID,然后查找手机本地数据库是否有此用户ID的昵称和头像,如没有则调用APP服务器接口通过用户ID查询出昵称和头像,然后保存到本地数据库和缓存,下次此用户发来信息即可直接查询缓存或者本地数据库,不需要再次向APP服务器发起请求。

昵称和头像的更新:当点击发送者头像时加载用户详情时从APP服务器查询此用户的具体信息然后更新本地数据库和缓存。当用户自己更新昵称或头像时,也可以发送一条透传消息到其他用户和用户所在的群,来更新该用户的昵称和头像。

方法二:从消息扩展中获取昵称和头像

昵称和头像的获取:把用户基本的昵称和头像的URL放到消息的扩展中,通过消息传递给接收方,当收到一条消息时,则能通过消息的扩展得到发送者的昵称和头像URL,然后保存到本地数据库和缓存。当显示昵称和头像时,请从本地或者缓存中读取,不要直接从消息中把赋值拿给界面(否则当用户昵称改变后,同一个人会显示不同的昵称)。

昵称和头像的更新:当扩展消息中的昵称和头像 URI 与当前本地数据库和缓存中的相应数据不同的时候,需要把新的昵称保存到本地数据库和缓存,并下载新的头像并保存到本地数据库和缓存。
上面是两种环信文档中介绍的,我采用的算是第一种(其实我感觉那种都不算。。。),就是把服务器上的昵称和头像填到聊天界面和消息列表界面中,表示本地数据库什么的,一点都不知道,环信你提供了么?在demo中倒是看到了,但是那个又不在EaseUI中,而且还涉及到另一个.framework,就没有导入。如果小伙伴有更好的方法,也可以简信告诉我。

所以大体的思路就是,服务器请求到的数据,填到消息列表和聊天界面上。

在EaseUI中,负责消息列表的是EaseConversationListViewController这个类

负责聊天界面的是EaseMessageViewController这个类

我的做法是分别用两个类继承他们两个,ChatViewController继承EaseMessageViewController,ChatListViewController继承EaseConversationListViewController。
然后在我继承的这个两个类中实现环信提供的代理方法,尽量不去改环信的EaseUI代码(里面那代码改起来也的疯啊,而且那么多,以后自己改的那些你还记得么?,还不如整一个新类)。

先说消息列表,有这几需求

需求:

1、昵称和头像

2、消息的时间,因为EaseUI默认的是日期,而不是几点几分

3、下拉刷新和空视图

4、点击推出的聊天详情

解决方案:

1、昵称和头像

EaseUI已经给我们提供了代理方法,只要实现代理方法,就可以自定义cell的样式了。方法名:

- (id<IConversationModel>)conversationListViewController:(EaseConversationListViewController *)conversationListViewController modelForConversation:(EMConversation *)conversation

此代理是在EaseConversationListViewControllerDataSource协议中的,所以ChatListViewController(继承EaseConversationListViewController的类)要遵从协议,并且self.dataSource = self;
此方法是返回一个遵从IConversationModel代理的model,这个model就是cell的数据源,EaseUI已经帮我们写好了一个model,我们直接创建,然后赋值就好了

- (id<IConversationModel>)conversationListViewController:(EaseConversationListViewController *)conversationListViewController                                    modelForConversation:(EMConversation *)conversation{    //用环信提供的model就可以了    EaseConversationModel *model = [[EaseConversationModel alloc] initWithConversation:conversation];    //然后根据用户名  往上面赋值    //self.imageAndNameArray为自定义的数组,其中存储的是从自己服务器上请求下来的数据    //数据包括,昵称,头像和默认图片    for (HPChatListDataModel *dataModel in self.imageAndNameArray) {        if ([dataModel.mobile isEqualToString:model.conversation.conversationId]) {//根据用户名对应起来            model.avatarURLPath = dataModel.pic;//头像的网络图片            model.avatarImage = [dataModel getDefaultImage];//头像的默认图片            model.title = dataModel.name;//昵称        }    }    return model;}

主要是在那个for循环中,给model赋值,就好了
但是这里有个问题,如果你们服务器返回的头像是圆的,那么会看起来头像四角是灰色的,这是因为环信的消息列表中,头像的imageView的背景颜色,设置成灰色的,所以,只能在EaseConversationListViewController类的

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

方法中加上,

cell.avatarView.imageView.backgroundColor = [UIColor whiteColor];

2、消息的时间

环信提供的方法:

- (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController

方法的实现:

//时间- (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController       latestMessageTimeForConversationModel:(id<IConversationModel>)conversationModel{    NSString *latestMessageTime = @"";    EMMessage *lastMessage = [conversationModel.conversation latestMessage];;    if (lastMessage) {        //这个方法是环信提供的        latestMessageTime = [NSDate formattedTimeFromTimeInterval:lastMessage.timestamp];    }    return latestMessageTime;}

其中方法formattedTimeFromTimeInterva是环信EaseUI中提供的,要包含头文件

#import "NSDate+Category.h"//环信时间分类

3、下拉刷新和空视图

//打开下来刷新    self.showRefreshHeader = YES;

实现下拉刷新的方法,

//下拉刷新  实现以下- (void)tableViewDidTriggerHeaderRefresh{//super必须要有  要不会有问题    [super tableViewDidTriggerHeaderRefresh];    //这里写下拉的方法}

空视图

判断是否为空视图的话,直接判断self.dataArray.count就好了,父类的数据源数组就是这个。

4、点击推出的聊天详情

因为聊天详情要用我们自定义的ChatViewController(继承于EaseMessageViewController),所以点击推出的应该是我们自定义的,所以要实现代理方法:

- (void)conversationListViewController:(EaseConversationListViewController *)conversationListViewController            didSelectConversationModel:(id<IConversationModel>)conversationModel;

实现:

- (void)conversationListViewController:(EaseConversationListViewController *)conversationListViewController            didSelectConversationModel:(id<IConversationModel>)conversationModel{    EaseConversationModel *model = (EaseConversationModel *)conversationModel;    //自定义点击cell推出的viewcontroller    ChatViewController *viewController = [HPChatViewController chatViewControllerWithConversationChatter:model.conversation.conversationId title:model.title imageUrl:model.avatarURLPath defaultImage:model.avatarImage];    [self.navigationController pushViewController:viewController animated:YES];}

聊天界面

需求:

1、替换昵称和头像

2、去掉多余的功能按钮

环信EaseUI提供的方法

- (id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController                           modelForMessage:(EMMessage *)message

实现:

- (id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController                           modelForMessage:(EMMessage *)message{    //用户可以根据自己的用户体系,根据message设置用户昵称和头像    id<IMessageModel> model = nil;//EaseMessageModel是环信EaseUI提供的model  直接引用就好了    model = [[EaseMessageModel alloc] initWithMessage:message];    //分两种情况  一种是当为当前用户的时候    if ([model.nickname isEqualToString:[EMClient sharedClient].currentUsername]) {        //默认图        model.avatarImage = [UIImage imageNamed:@"DefaultImg"]        //网络图        model.avatarURLPath = accInfo.pic;    }else{//当为对方的时候        model.avatarURLPath = _imageUrl;//网络图        model.avatarImage =  [UIImage imageNamed:@"DefaultImg"];    }    model.nickname = nil;//用户昵称    return model;}

2、去掉多余的功能按钮

    //删除电话和视频   //这里为什么要移除3两次,因为执行第一次后,后一个的索引变成了3    [self.chatBarMoreView removeItematIndex:3];    [self.chatBarMoreView removeItematIndex:3];

好了 完成

对了,我这里的聊天界面,只是支持单聊,以后项目如果支持群组的话 ,那再来更新

1 0
原创粉丝点击