Global IM UIKit 架构分层
Global IM UIKit 把「视图」「状态」「数据」「回调」「渲染模型」「样式」拆成六层,另有一个可替换的路由层。这样做的直接收益是:业务可以替换任意一层而不重写页面,也便于单元测试(注入 DataSource / 假 ViewModel)。
依赖方向
GlobalUIKit -> IMKit -> IMLib(公开接口)
分层与数据流
Text
ViewController(ChatListViewController / ChatViewController / ChatInputController)
│ 绑定 / 订阅
▼
ViewModel(ChatListViewModel / ChatViewModel) ← 只调用 IMLib 公开接口
│ stateChanged / messagesChanged / sendStateChanged
▼
DataSource(ChatListDataSource / ChatDataSource) → 列表数据
Delegate(ChatListDelegate / ChatDelegate) → 宿主交互回调
CellModel(ChatCellModel) → 单条消息的渲染模型
Theme(ChatUITheme) → 颜色 / 字体 / 布局令牌
Router(ChatRouter) → 会话 / 资料页跳转(宿主可替换)层与组件
| 层 | 职责 | 组件(Swift 符号) |
|---|---|---|
| ViewController(视图 / 生命周期 / 输入) | 渲染视图、处理生命周期与用户输入,不持有业务状态 | IMPChatListViewController、IMPChatViewController、IMPChatInputController |
| ViewModel(状态机与业务编排) | 状态机:加载、增量合并、发送/已读/撤回等编排,向视图暴露状态 | IMPChatListViewModel、IMPChatViewModel |
| DataSource(列表数据) | 向列表提供数据(会话 / 消息),支持测试注入 | IMPChatListDataSource、IMPChatDataSource |
| Delegate(交互回调) | 把用户交互回调给宿主(导航、详情、重发由宿主实现) | IMPChatListDelegate、IMPChatDelegate |
| CellModel(渲染模型) | 把消息转换为可渲染模型(时间、状态、已读、撤回) | IMPChatCellModel |
| Theme(样式令牌) | 统一颜色 / 字体 / 布局令牌,支持浅色、深色与 Dynamic Type | IMPChatUITheme |
| Router(路由,宿主可替换) | 统一路由入口,默认 push/present,可注入自定义实现支持深链 | IMPChatRouter |
状态机约定
| ViewModel | 状态 / 事件 | 约定 |
|---|---|---|
| ChatListViewModel | stateChanged(state)、error(err) | load / refresh / loadMore 幂等;合并 CONVERSATION 增量;错误可重试 |
| ChatViewModel | messagesChanged(change)、sendStateChanged(localId,state)、typingChanged(userId,typing) | 按 seq 去重排序;发送状态机;已读去重节流;合并撤回/回执事件 |
事件与载荷语义见各组件页;交互回调只通知宿主,不自行导航(导航交给 ChatRouter 或宿主)。
线程与生命周期
- ViewModel 的回调默认在主线程投递,视图层可直接更新 UI;耗时逻辑由 ViewModel 内部串行队列处理。
- ViewController 在
deinit/viewDidDisappear时取消订阅,避免事件回调持有已释放的视图。 - 输入区高度变化通过
heightChanged通知宿主,键盘避让由宿主容器处理。 - 主题切换可在运行中生效,不需要重建 ViewController。
下一步:快速开始 或 ChatListViewController。