XMPPFramework开发(六):聊天功能和消息回执

111396375-d79631fa0c7527f6

前言


前面我们几篇文章我们一直在说关于XMPPFramework中好友关系相关的东东,今天即时通讯最重要的是什么?通讯聊天呀,所以,我们今天就说一下XMPPFramewor聊天的实现.SDChat比较简陋的聊天界面如下所示.

121396375-889ef49bb9357dc3

XMPPFramework实现聊天功能的相关方法


在XMPPFramework中实现聊天功能的类主要是XMPPSteamXMPPMessageArchivingXMPPMessageArchivingCoreDataStorage,其中XMPPSteam的作用主要是消息发送、消息接受等一系列相关的代理回调.XMPPMessageArchivingXMPPMessageArchivingCoreDataStorage则是消息历史记录本地查询的相关类.下面则是关于聊天的相关方法.

 

XMPPFramework的聊天功能实现


聊天功能的逻辑相对好友方面的逻辑说还是比较简单的.我们先看一下两个用户之间发送一条消息的流程图.如下所示.

131396375-37ac085a38f4757d

通过上面的流程图我们已经对XMPPFramework的发送消息的整体流程有了一个大概的了解.那么接下来我们就说一下SDChat中关于聊天功能的代码实现.

首先,在SDXmppManager中我们先对聊天功能的本地化存储对象进行初始化.

上面.我们已经对本地化存储对象进行了设置,接下来,我们现在SDChatVC聊天界面中做一个准备工作,那就是获取聊天历史记录.我们需要通过SDXmppManager中的messageContext(上下文属性对象)来获取到对应的数据.

然后我们需要调用CoreData中的NSFetchRequest(获取数据的请求,通过被管理数据的上下文来执行查询)这个类的相关方法查询对应的数据.这里需要使用到上述的上下文对象context.数据库中的数据很多,我们需要的只是与当前聊天对象的记录,所以我们还需要使用谓词来添加过滤条件.这样我们就可以获取到我们想要的数据了.如下代码所示,fetchedObjects就是我们所需要的数组,数组中的对象类型为MPPMessageArchiving_ Message_CoreDataObject.

上面关于CoreData数据库的查询看似很是麻烦,但是系统已经帮我们写好了代码块了,我们只需要输入”fetch”就可以找到如下的列表,我们选择第一个”fetch – Core Data Fetch”就把上面所的所有的代码输入了.如图所示.

141396375-6bb36ee62a10c251

那么,准备工作做好之后,我们就需要开始发送消息了.发送消息也是十分的简单,我们使用- (void)sendElement:(NSXMLElement *)element这方法就可以发送我们的消息了,但是在此之前,我们需要组装我们所需要发送的XMPPMessage消息对象.我们设置类型为”chat”类型,然后设置需要接受者的JID,接受者的信息需要从联系人列表页面中传值过来.然后我们添加XMPPMessage的Body信息为我们的文本信息.代码如下.

那么接下来,我们就发送的我们的消息即可.

发送如果成功(对方接收到消息)之后,我们就需要在-(void)xmppStream:(XMPPStream *)sender didSendMessage:(XMPPMessage *)message发送消息成功这个代理方法中做数据刷新的操作代码如下所示.

作为消息的接受者也是要聊天记录的刷新的,这个需要在-(void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message这个方法中进行代码实现,具体如下所示.

 

消息回执


上面的模块,我们好像把消息的一个流程做完了,但是其实不然,如果只有上面的几步,我们是实现了基本的即时通讯,但是会出现信息不同步的Bug,那就是我们同时发送两条消息的时候,我们的页面上只会出现上一条消息,最后发送的消息是不出现的,这是什么原因造成的呢?用户发送的消息,其实是没有回执.就是说A发送消息给B.而B又一致不回复.所以对于客户端A来讲压根不知道消息是否发送成功.所以我们需要在每一条消息的后面添加回执消息,这个需要在组装消息之后进行添加.如下所示.

那么当接受者接受到消息之后,我们需要往发送者发送回执消息,通知发送者消息已经接受成功了,代码如下所示.

有了消息回执之后,但是如果接受者不在当前的聊天页面却是在线的,我们发送一条消息何如发送回执消息呢?这就需要我们在AppDelegate里面设置一个接收消息的代理方法用来发送回执消息,代码和上面的一样.这里就做截图了,不进行重复操作了.

151396375-ec1cc8e8aaad44c4

聊天记录的展现


161396375-987c8753d0dc133e

上面我们基本把聊天功能实现完成了,如何实现聊天记录的展现呢?页面的整体是一个tableView,根据文字消息的内容,我们计算出每一个气泡的高度,然后计算出每一个Cell的高度.那么逻辑上是这样的,实际上在SDChat中是如何实现的?这里我就一个一个功能点来说明.

对于每一个聊天记录的Cell,我们把文字Label添加到气泡的UIImageView对象上去.然后气泡的UIImageView对象再添加到每一个Cell上.Cell主要有两个功能点,一个就是文字的高度,另外一个就是气泡的拉伸问题.

171396375-9293808779ec6c16

首先,我们说一下计算文字高度的方法.我们使用的是NSString中的一个方法,我们输入文字的可展示范围以及文字的字号就可以.可以计算出一段文字的Rect.

那么计算出文字高度之后,我们如何让我们的气泡适应文字的尺寸呢?我们需要对图片进行拉伸操作,我们使用的是如下的方法.其中参数1代表从左侧到指定像素禁止拉伸,该像素之后拉伸,参数2代表从上面到指定像素禁止拉伸,该像素以下就拉伸.

在聊天页面的tableView的其实就没有什么好说的,最多就是一个去除Cell之间的间隔线问题,我们只需要下面一行代码即可.

聊天历史记录获取Bug以及优化建议


其实这个Bug是关于中文的问题,在设置个人的电子名片和聊天记录的时候都会出现这个问题,那么就是如果我们输入了中文,那么下一次获取数据的时候可能只有”???”了,问题待解决,如果有解决的大神,希望能告诉骚栋,红包答谢~😄

结束


呼呼,写到这一篇,骚栋XMPPFramework的这个专题也进行了一大半了,下一篇骚栋将写一下关于好友上下线的状态的获取.希望大家能继续关注,如果有任何问题欢迎联系骚栋,谢谢.最后还把SDChat的传送门送给大家.大家可以对照着Demo来看本篇博客.

–>SDChat传送门🚪

1 收藏 评论

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部