Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IM 即时通讯技术篇-技术实现细节 #7

Open
ChenYilong opened this issue Jan 20, 2017 · 0 comments
Open

IM 即时通讯技术篇-技术实现细节 #7

ChenYilong opened this issue Jan 20, 2017 · 0 comments

Comments

@ChenYilong
Copy link
Owner

#技术实现细节

IM系列文章

IM系列文章分为下面这几篇:

本文是第二篇。

本文将以开源项目 ChatKit-OC 为例进行介绍:

正文

ChatKit-OC 我们专门为社交场景开发的开源组件:ChatKit-OC,star数,1000+。

项目地址:ChatKit-OC

下文会专门介绍下技术实现细节。

先看下现在 IM 领域的轮子有什么问题:

  • Demo 太多,是时候该来一款 Lib 了;
  • 闭源的太多,是时候来一款开源的了;
  • 部分开源的太多,是时候来一款 100% 开源的了(iOS 端)
  • 手撕 Frame 的太多,是时候来一 AutoLayout 款了;
  • 自定义能力太弱的太多,是时候来一款可高度自定义的了;

ChatKit-OC 正是为解决这些问题做的,它的特点如下:

  • 集成方法简单,但可扩展性好。
  • iOS 端代码完全开源,你能看到完整的建立 Socket 连接,以及维持心跳的所有步骤。
  • 原生语言开发,利于调试,并非采用C++库。
  • Masonry 布局
  • 友好的 API 设计
  • 接地气
  • 支持 CocoaPods
  • 不需要改源码,不需要设 Delegate
  • 不需要在代码里调整聊天气泡位置

效果展示:

enter image description here

enter image description here

enter image description here

enter image description here

最近联系人 | 语音消息,根据语音长度调整宽度 | 图片消息,尺寸自适应
-------------|-------------|-------------|-------------
enter image description here|enter image description here | enter image description here

地理位置消息 失败消息本地缓存,可重发 上传图片,进度条提示
enter image description here enter image description here enter image description here
图片消息支持多图联播,支持多种分享 文本消息支持图文混排 文本消息支持双击全屏展示
enter image description here enter image description here enter image description here

紧凑的API设计:门面模式

使用门面模式,使接入方仅仅需要与一个类打交道,也就使得 API 更加紧凑。

极简参数:

像 UIAlertView 一样,你只需要使用 title 去 init 后,然后直接调用 show 就能达到预期的效果。采用了类似的 API 设计,

隐藏细节:

设计 API时尽量隐藏细节,尽量提供默认实现。

就像 SDWebImage 被使用最多的功能就是 TableView 图片的加载,

只需要传入占位图和图片 URL 两个参数,就能完成复杂的异步加载展示。

无侵入的用户系统接入

需求:与用户的用户帐号体系完全隔离,只需要提供一个 ID 就可以通信,接入方可以对该 ID 进行 MD5 加密后再进行传输和存储,保证开发者用户数据的私密性及安全。

基本的流程示意:

正如图中所示,ChatKit 在需要展现用户图像等信息到 UI 上时,会拿着 ID 去回调一个 Block,这个 Block 需要将对应的用户头像等信息 callback 给 ChatKit,进而展现在 UI 上。

其中最关键的部分是,ChatKit 提供的这个 Block,这个 Block 需要用户自己实现。对这个 Block 的具体实现感兴趣的话,可以看下这篇:

《有一种 Block 叫 Callback,有一种 Callback 做 CompletionHandler》

面向 ID 编程

  1. 底层协议:Client -- ClientID
  2. 上层UI:Conversation -- ConversationID

ClientId:

WebSocket 通信是 Session 对 Session 的通信,我们将概念简化为 Id 对 Id 的通信,这样一来,两个 APP 只需要 ID 就可以聊起来,这个 ID 我们取名叫 ClientId。

在 ChatKit-OC 的 UI 实现中,体现在对话页面的初始化,你只需要传递一个id,对话id,即可。你同样可以使用ConversationID也就是对话ID来初始化。这样简洁的 API 设计,做法类似 UIAlertView 的初始化只需要传一个 title 就可以。

Conversation(对话)这个概念,我们在使用其他的聊天协议时,比如XMPP,会有单聊和群聊之分,我们在 ChatKit-OC 中,将这个概念简化,不区分单聊群聊。这样一来,你在初始化时就会节省一个概念,而且可以达到只需要一个 ID 就能初始化一个对话页面的目的。在 ChatKit-OC 中我们通过对话中的人数来群分单聊群聊,当然你也可以为对话添加额外的字段,来准确地标记。每个 Conversation 对象都有一个 Attribute 属性,可以自定义字段。

可维护性

传统方式设置 View 坐标,或 颜色的问题:

  1. 直接写坐标可维护性太差
  2. 定义成宏,无法满足组件化后的自定义需求
  3. 失去动态更新能力

为了解决以上问题,ChatKit 使用了 UI 配置文件的方式来提高可维护性:

将配置文件以 JSON 文件,或 plist 文件的方式,我采用的是 plist 文件形式,放置在 bundle 中,让 bundle 文件可以自定义,图片等多媒体资源也就同样可以自定义了。如果在App运行中覆盖对应路径,也就能达到动态更新应用主题的目的。

  • 易于维护
  • 利于动态更新
  • 安卓和iOS公用一套 UI 配置

下图是 ChatKit 中部分可自定义项:


做法类似:

  • 安卓开发中的 style xml
  • 网页开发中的 css
  • 微信团队做法类似。淘宝的一些app也采用了。
    微信团队就是如此,软件开发团队从来不负责改坐标、颜色等 UI 参数,这些都是 UI 设计 团队去做。也是采用配置文件。淘宝的聚划算团队也使用了类似的策略,只不过是使用了 JSON 文件的形式。

可拓展性

使用 CocoaPods 集成,在 Demo 层面能实现红包这样大粒度的自定义业务模块,

效果图如下所示:

需要几个 API:

12个接口:

自定义项 公开API 备注
自定义消息 2 -registerSubclass+classMediaType
自定义Cell 4 -registerCustomMessageCell+classMediaType-setup-configureCellWithData:
自定义插件 6 -registerCustomInputViewPlugin+classPluginType-pluginIconImage-pluginTitle-pluginDidClickedsendCustomMessageHandler

效果图:

  • | - | -
    -------------|-------------|-------------
    | |
    | |

如何做到在Demo层面进行这样的拓展?
最关键的是:插件映射机制:

比如下图中输入框底部的这些可以点击的插件,ChatKit-OC 提供了一个可变字典,能让用户操作,添加元素。在需要展示 时会去该字典中拿View,因此只要提前进行了映射,就可以加载上。

这种映射机制应用在了:

  • 自定义cell类型
  • 自定义Message类型
  • 自定义输入框底部插件

封装程度高

现状,现在社区中很多轮子,大多数自定义消息的做法,是在“自定义字符串”,对话双方传输的是字符串,接收后需要自己去做序列化、反序列化。

ChatKit-OC 则封装程度更高,发送接收消息时,已经将所有的自定义消息,序列化和反序列化好。你只需要操作 Model 就可以。

IM系列文章

IM系列文章分为下面这几篇:

本文是第二篇。


Posted by 微博@iOS程序犭袁
原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant