做了一段时间的IM,这次把之前遇见的一些坑记录一下,后面有时间把聊天部分,做一些分享,希望对大家有点帮助。之前在网上一直看的项目中,在开发中途遇见坑说得比较少。如果首次写聊天的话可能遇见的问题会比较多,这里我主要说说自己遇见坑。欢迎大家拍砖哦。要不同的意见麻烦提出来,谢谢了。大家共同进步!
对你有点用处的话,记得星星哦!
-
消息的撤回、删除、复制
-
语音、文字、图片
-
未读人数
-
项目中自定义的其他消息样式
-
实际项目中有云盘、视频播放、朋友圈...
- 界面布局的时候最开始使用了UITableView+...Cell的第三方自动计算高度,因项目聊天样式较多,在使用xib布局的时候只布局了左右两个样式,通过隐藏和显示来控制样式。因开发的时候,没用过多的数据测试,导致数据较多时十分卡顿,老板说的是卡卡卡,比老牛拉破车还卡.这种卡顿是在滑动页面的时候就明显感觉到了。
找到问题的原因之后,以下解决方案:
-
先是手动计算高度同时把Xib布局的冲突解决掉之后。滑动页面流畅度可以接受了。当然想达到比较好的流畅度frame布局可能会更好些。
-
同时这里Xib在采用Xib布局的时候,层级尽量少。层级较多会影响流畅性哦。
- 最开始的时候,因为我们涉及到每条消息的未读人数的处理,通过服务器回执的未读数去替换当前聊天消息模型。当聊天人数达到一定层度的时候,看消息的人就较多了。这时回执比较频繁,当时回执回来刷新某一条数据,这时界面又卡其来了。在这个过程中,未读数的处理。客户端处理得有一些问题。在滑动页面的时候把当前未读消息发给服务器,服务器成功返回了表示已读。服务器消息是要排队的,频繁回执给服务器。服务器频繁推给客户端。导致刷新页面太频繁了。在我们客户端端就卡起来了。(此时我们替换消息的问题是,在当前所有消息遍历找要替换的数据)
找到问题的根源后,采用了以下方法进行解决:
- 把自己发送的消息单独保存起来,未读数的替换只需要替换当前自己发送的。
- 并且在确定高度的时候(heightForRowAtIndexPath)在每一个模型中放一个当前消息的位置。在替换消息的时候,能够根据需要快读找到要替换的消息。千万不要写在这里 cellForRowAtIndexPath确定位置。要不然就又坑了。
通过上面的方法流畅度基本上达到要求了。只从自己发的消息找要替换的数据,而且位置已经确定。直接替换即可。
- 最开始的时候我们使用的是FMDB,
- 在存数据的时候直接存的模型data,发现当数据比较多的时候,又是卡顿。(我们没用好) 存的时候感觉比较快,读的时候数据多的时候卡爆了。这里还有一个,就是把图片也转Data存进去了。当首次进入页面的时候,如果里面连续几十张图片,这是从外面点进去都要等一会儿。卡死主线程了。
发现问题我们就解决问题:
- 数据库我们使用了微信开源的WCDB,各方面都要爽一些。不用谢SQL语句了。
存模型,取的也是模型,毫无卡顿。
- 图片的处理我们使用把图片转data存沙盒中,根据图片地址和消息的中的关键字段做为key存沙盒中。这时数据库只需要存地址即可。根据这个地址作为的key,找出图片。经测试图片几十张也没有感觉。这里我们只缓存了自己发的图片。对方的图片SdwebImageView做了缓存。缓存自己的图片目的是发送使用做处理。这里使用了NScache缓存处理正在码代码中...
- 经过上面的处理普通情况下,流畅度已经能接受了。
但是在某天有一个同事发了整页,都是系统键盘自带的表情,我去又卡起来了。而且其他同事也发,又是卡卡卡,这种心情大家都能理解(另外加一句我们公司有个测试情况,就是大家在一个规定的时间周一到周五每天中午半小时测试、周末晚上测试半小时。老板及所有的员工都在)。因为我们用的是普通的UILable没做任何处理。
这是我想起了YYLable,异步渲染,让界面要多流畅有多流畅.更换之后流畅度增加不少。
- 第一版聊天出来之后,多人一起测试。发现漏消息十分严重。 经排查我们在存消息的时候,出现了重要问题。
- 当前解决方案:
- 根据socket推过来的消息,只要socket连起在就存。
- 并且当接受到消息之后,返回给服务器(间隔很短时间返给服务器接受到了当前最大的一条消息)。如果不回执的话服务器就会在发消息的时候推送多条,这里要自己排重。
- 而且网络断开 socket重连的时候也会拉取消息,有效保证了数据
在这里我们要做像钉钉和微信一样的9人头像。而且没有头像的时候,头像的位置要显示姓名的最后一个字。
这里我使用了9个按钮,按钮有图片和文字能。以为写出来在数据较多的时候会卡,结果就通过把9个头像按钮,根据实际头像个数来计算frame调整位置,隐藏不需要按钮。结果写出来之后。效果还不错。流畅度能达到要求。随便说一句这个头像有三个人写过。嘿嘿。