ios聊天demo
自己写了个聊天界面,因为以前做开发的时候开发过聊天功能,现在把其中的聊天模块分离出来,cellOptimize分支代码对数据源的结构体作了优化。
项目运行:
该项目集成了一般的聊天功能,包含文字、图片、音频,通讯使用xmpp协议,代码里面也有xmpp的消息接收、消息发送。本地使用coredata保存聊天的数据:
数据库:
Mes实体类author表示所有者
content表示聊天内容,若是文字保存文字,若是图片或者音频保存在服务器的链接。
date表示消息的日期
from表示发送方
to表示接收方
type表示消息类型,包括time时间戳、图片、音频、文字,几类消息类型使用type数字区分。
type结构体:
消息类型枚举类配置文件:
配置文件config.plist里配置了本身用户的名字、头像,好友用户的名字、头像。
config.plist配置文件该项目最重要的Vc是chatVc,chatVc是一个tableView,下拉时从数据库里拉取聊天数据,数据发送后将发送的数据保存在本地数据库(图片和音频是发送后直接保存到数据源,发送完成后才保存到本地数据库)。
音频的录制使用AVAudio,录制成功后需要转码,因为录制的caf文件格式不能正常播放,这里使用的是c++的一个库叫lame,将文件转成mp3格式后再上传。
富文本的绘制代码使用的是drawRect,表情是本地自定义了一些表情图片,发送的时候解析文本,将是表情图片的地方使用表情图片绘制
后台地址:
图片的上传需要有一个上传接口,我用的是AFN表单上传,需要配置图片上传的地址,在pch预编译文件里:
image上传地址难点:
cell的绘制,文字和音频展示使用了重用,图片展示使用cellfor方式。图片的展示我考虑的是在上传和下载的时候在图片控件上添加了一个遮罩和一个上传/下载的百分比,上传/下载完成后去掉遮罩和这个百分比view,百分比的数据保存在数据源里,每次在绘制的时候去重新绘制遮罩和百分比(上传/下载完成后不需要绘制这两个view),这样重用该类型的cell应该是没有问题的,但是在实际编码中发现每次遮罩和百分比的展示都有问题。发现这个是cell重用的问题,下载或者上传图片的operation对cell的进度progress进行操作,如果有滑动,这些operation又会关联到不同的cell,这样就会导致一个展示的cell的进度条同时有几个 operation去更新它的progress进度,造成进度跳跃的效果。我的解决方案就是下载的cell不重用,思路是对这两种情况的图片cell使用两种identifier,一种是下载/上传完成的picFinish_identifier,这个作为重用的cell,而未下载/上传完成的cell使用picNotFinish_identifier,这种类型的cell不重用,而且在图片下载期间避免这种cell被销毁,使用一个字典对象将这些正在下载/上传完成的图片进行存储,这样就避免了同一个operation去同时影响几个cell的progressView问题。下载完成后再将这些picNotFinish_identifier的cell从字典对象里删除就行了。这样基本上解决了进度条跳跃的问题。思路是这个思路,实践起来出了几个问题,主要是下载/上传完成后生成的picNotFinish_identifer的cell从字典对象里remove掉后cell并没有被释放掉,这一点的确很难理解是什么原因,因为直接使用cellfor生成cell的方式cell是能够被释放掉的,可能是代码哪里没有考虑到。
优化之路:
主要是对cell里面对图片操作的相关地方进行适当的优化,缩小图片尺寸,再将图片添加到uiimageView,这样能使内存消耗明显降低。
代码地址:https://github.com/dinner/chat
该repo有两个分支,cellOptimize是最新优化的一个分支,将cell优化了下,以前的cell太冗余复杂,不够简洁,数据源也重新设计了下。有兴趣的朋友可以一起研究下。