# 4\_3-带货场景-聊天室

* [1 功能概述](#_1-功能概述)
* [2 核心类介绍](#_2-核心类介绍)
  * [2.1 PLVECChatroomViewModel](#_21-plvecchatroomviewmodel)
    * [2.1.1 生命周期](#_211-生命周期)
    * [2.1.2 获取聊天记录](#_212-获取聊天记录)
    * [2.1.3 发送消息](#_213-发送消息)
    * [2.1.4 消息数组](#_214-消息数组)
    * [2.1.5 监听与回调](#_215-监听与回调)

#### 1 功能概述

聊天室模块包括发言、点赞、历史记录、欢迎语等功能。聊天室模块在UI、交互、功能上，相较于其他模块，都会更复杂更庞大。因此设计、搭建、维护一个聊天室，也是一件较为费时费力的事情。我们推荐直接使用保利威封装好的聊天室模块，该部分代码完全开源，支持直接使用，以及二次开发。

#### 2 核心类介绍

**2.1 PLVECChatroomViewModel**

`PLVECChatroomViewModel` 是带货场景 Scene 层聊天室的核心类，由于一个应用只允许存在一个聊天室，所以 `PLVECChatroomViewModel` 采用的是单例的模式，负责创建、持有、销毁 Common 层聊天室核心类 `PLVChatroomPresenter` 的实例对象以及与 Common 层聊天室模块进行通信，核心类 `PLVECChatroomViewModel` 提供功能如下：

1. 对 View 层提供发送消息的接口；
2. 管理 Common 层返回的消息模型；
3. 在 View 层需要刷新 UI、更新列表数据时，通过回调通知 View 层。

**2.1.1 生命周期**

`PLVECChatroomViewModel` 是单例类，进入直播间启动聊天室的时候调用 -`setup` 方法，离开直播间时调用 -`clear` 方法，代码如下：

```objective-c
// 使用新的直播间数据启动聊天室管理器
[[PLVECChatroomViewModel sharedViewModel] setup];
// 退出前调用，用于资源释放、状态位清零
[[PLVECChatroomViewModel sharedViewModel] clear];
```

代码注释提到的“直播间数据”指的是 `PLVRoomDataManager` 单例持有的 `roomData`。

**2.1.2 获取聊天记录**

Common 层聊天室核心类 `PLVChatroomPresenter` 在初始化完毕之后，会自动获取第一页的聊天记录，获取更多聊天记录代码如下：

```objective-c
[[PLVECChatroomViewModel sharedViewModel] loadHistory];
```

`-loadHistory` 使用在 2.1.1 的 `-setup` 方法里初始化的 presenter 对象，调用 Common 层聊天室模块获取聊天室记录。

**2.1.3 发送消息**

`PLVECChatroomViewModel` 类提供带货场景所需的发送消息的API，具体接口定义如下：

```objective-c
/// 发送文本消息
/// @param content 消息文本
/// @return YES表示数据将有更新，可等待收到回调后刷新列表；NO表示socket未登录或房间关闭，可进行toast提示
- (BOOL)sendSpeakMessage:(NSString *)content;

/// 发送礼物消息
/// @param data 礼物消息data字段
/// @param tip 礼物消息tip字段
/// @return 是否成功发送的布尔值
- (BOOL)sendGiftMessageWithData:(NSDictionary *)data tip:(NSString *)tip;

/// 发送自定义消息
/// @param event 自定义消息event字段
/// @param data 自定义消息data字段
/// @param tip 自定义消息tip字段
/// @param emitMode 自定义消息emitMode字段
/// @return 是否成功发送的布尔值
- (BOOL)sendCustomMessageWithEvent:(NSString *)event
                              data:(NSDictionary *)data
                               tip:(NSString * _Nullable)tip
                          emitMode:(int)emitMode;

/// 发送点赞消息
/// 点赞数的实时更新通过监听roomData的likeCount获得
- (void)sendLike;
```

**2.1.4 消息数组**

`PLVECChatroomViewModel` 类提供以下消息列表数组，作为聊天室 View 层的数据源：

```objective-c
/// 全部消息数组
@property (nonatomic, strong, readonly) NSMutableArray <PLVChatModel *> *chatArray;
```

**2.1.5 监听与回调**

`PLVECChatroomViewModel` 提供了属性 `delegate` 用于设置回调监听，属性 `delegate` 遵循协议 `PLVECChatroomViewModelProtocol`，用于在 View 层需要刷新 UI、更新列表数据时，通过回调通知 View 层：

```objective-c
@protocol PLVECChatroomViewModelProtocol <NSObject>

@optional

/// 返回本地发送的公聊消息（包含禁言的情况）
/// 用于刷新列表、滚动列表到底部
- (void)chatroomManager_didSendMessage;

/// 返回socket接收到的公聊消息
/// 用于刷新列表、显示新消息提示
- (void)chatroomManager_didReceiveMessages;

/// socket通知有消息被删除（1条或多条）
/// 用于刷新列表
- (void)chatroomManager_didMessageDeleted;

/// 获取历史聊天记录成功时触发
/// 用于刷新列表，停止【下拉加载更多】控件的动画
/// @param noMore 是否还有更多历史消息，YES表示已加载完，此时可隐藏【下拉加载更多】控件
/// @param first  是否是初次加载历史消息，初次加载需滚动列表到底部
- (void)chatroomManager_loadHistorySuccess:(BOOL)noMore firstTime:(BOOL)first;

/// 获取历史聊天消息失败时触发
/// 用于停止【下拉加载更多】控件的动画
- (void)chatroomManager_loadHistoryFailure;

/// 当前时间段内如果有用户登录聊天室（包括自己），间隔2秒触发一次
/// @param userArray 登录聊天室的用户数组，如果为nil，表示当前时间段内当前用户有登录事件
- (void)chatroomManager_loginUsers:(NSArray <PLVChatUser *> * _Nullable )userArray;

@end
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://polyv.gitbook.io/document/docs/live/ios/43-dai-huo-chang-jing-liao-tian-shi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
