源码地址:https://github.com/dinner/chat
该demo是基于openfire的聊天demo,openfire是基于xmpp的IM服务器。openfire环境搭建不多说,网上有很多,主要介绍下该demo的代码。
1、配置文件
selfUserHeaderUrl表示该用户自己的头像链接,friendHeaderUrl表示好友的头像链接。下面分别是自己的名字,好友的名字,超时秒数(时间间隔多久添加时间显示),比如说设置为5,最后一次发送消息和改次发送消息的时间间隔相差5秒时界面有时间间隔显示。
2、数据库
author:所属用户,也是当前用户
content:内容
date:消息时间
from:发送方
to:接受方
type:消息类型 0表示文字 1表示音频,2表示图片,3表示时间 对应的枚举对象是mesType_enum。
3、pch文件
这里我定义的SERVER是另一个服务,主要处理图片上传,用户登录等。OPENFIRE_SERVER是openfire的服务,两者分开。
4、逻辑
该聊天模块是我从自己做的app里面单独弄出来的,系统有两个服务,一个服务SERVER处理登录,图片上传等跟用户相关的操作。另一个服务OPENFIRE_SERVER只处理聊天业务。用户登录时需要先请求SERVER验证账号密码,然后登录OPENFIRE_SERVER。注册时亦然,SERVER注册后去OPENFIRE_SERVER注册,密码相同。
5、主要遇到的问题
a、历史数据拉取时,聊天信息重复显示。
问题原因:先讲下我对消息的拉取逻辑,在chatVc里cellFrames是数据源,发送数据的时候会把数据写入到cellFrames里,同时保存到数据库。拉取的时候采用分页并按时间降序拉取,这个时候由于没有排除数据库里刚发送的数据所以会导致信息重复展示
解决:从数据库里拉取出来的对象跟cellFrames里面的最小时间消息进行比较,如果比这个时间小,则添加到数据源,反之则不添加。为了保证精度时间比较要精确到毫秒(由于这个,折腾了好久没搞清楚为啥几条信息的时间一样,最后才找到的原因,精确比较时间还是要精确到毫秒的 ^-^)。
b、uitalbeviewcell混合绘制
现在uitableview有6种类型cell,分别是From_text From_pic From_audio To_text To_pic To_audio,除了From_pic和To_pic之外其他都可以重用,由于pic上传和下载时会显示进度,重用会影响展示(多次实验得出结论,用deque重用会有这个问题)。cell的层级机构是:
cell.ContentView 里面添加ChatContentView对象,该对象负责cell里气泡数据的绘制,该类的成员:
backImageView绘制背景气泡,ContentLabel绘制文字,chatImageView图片,ContentAudio音频,对应几种消息类型,ChartCellFrame表示该cell数据源。图片上传下载的有进度展示,并且在数据源里面可以纪录图片上传和下载的断点位置,方便在下次进入或者cell重新绘制的时候显示正确的进度和保证正常的断点续传。