iOS

频道未读数管理

更新时间: 2024/03/14 17:08:38

如果您的应用 UI 上需要展示频道未读数,可参考本文介绍的流程获取频道内的消息未读信息并管理其变化。

游客接收到的消息无已读未读逻辑。不支持对游客展示消息的未读数。

未读信息定义

NIM SDK 中的NIMQChatUnreadInfo类定义了圈组频道的未读信息,其参数说明如下:

单击展开查看 NIMQChatUnreadInfo 的参数
参数 类型 说明
serverId unsigned long long 频道所属的服务器的 ID
channelId unsigned long long 频道的 ID
unreadCount NSUInteger 频道的消息未读数
mentionedCount NSUInteger 频道的@消息的未读数
maxCount NSUInteger 最大消息未读数
timestamp NSTimeInterval 服务器当前时间
ackTimestamp NSTimeInterval 已读时间戳(Unix 时间戳), 该时间戳对应的消息和早于该时间戳的消息都为已读消息
lastMessageTimestamp NSTimeInterval (可选)最后一条消息的时间戳 (Unix 时间戳)

您可通过多个方式获取NIMQChatUnreadInfo,具体方法参见本文的实现频道未读数持续监听实现频道未读数的直接获取

前提条件

开始集成前,请确保:

  • 已注册unreadInfoChanged新未读通知接收观察者,监听未读信息变更事件(NIMQChatUnreadInfoChangedEvent)。该事件信息中包含未读信息unreadInfolastUnreadInfo,分别表示“变更后的未读状态” 和“上一次通知时的未读状态”。
  • 已在频道内发送消息

使用限制

频道未读数管理存在如下与未读数相关的限制:

  • 所有未读消息(包括@消息)的消息阈值默认为 99 条。
  • @消息的未读数的有效期,默认为 7 天,即默认存储 7 天。

若需要扩展上限,可在控制台配置圈组子功能项(未读的@消息数-周期所有未读消息(包括@)的消息计数-阈值),具体请参考开通和配置圈组功能

实现流程

实现频道未读数持续监听

本文通过以下 UI 简图的场景为例,说明如何完成频道 1 未读数的监听、未读数的清零以及清零后的持续监听。

步骤1: 监听未读数

您需要订阅 频道 1 的未读数才能实现监听。完成如下两个子步骤后,当有新的消息下发到频道 1 ,SDK 将触发未读数变化监听事件 NIMQChatUnreadInfoChangedEvent 并上报。

订阅的频道仅在当前登录期间有效(因网络波动导致的断线自动重连除外)。如您调用logout:登出后,需要重新订阅。

  1. 进入服务器 1 后,调用getChannelsByPage:completion:方法刷新频道列表,得到频道 1频道 2频道 3频道 4

  2. 调用subscribeChannel:completion:方法订阅频道 1。 调用该方法时入参配置如下:

    参数 类型 说明
    targets NSArray<NIMQChatChannelIdInfo > 目标频道的 ID:传入您需要订阅的频道 ID 与该频道所属的服务器的 ID 组成的未读信息列表。
    operateType NIMQChatSubscribeOperationType 操作类型:订阅或取消订阅
    subscribeType NIMQChatSubscribeType 订阅类型,本场景下需传入NIMQChatSubscribeTypeChannelMsgUnreadCount订阅频道的未读数。

    该两步的示例代码如下:

    objcNIMQChatGetChannelsByPageParam *param = [[NIMQChatGetChannelsByPageParam alloc] init];
    param.serverId = serverId;
    [NIMSDK.sharedSDK.qchatChannelManager getChannelsByPage:param completion:^(NSError *__nullable error,NIMQChatGetChannelsByPageResult *__nullable result)
    {
        // 获取失败
        if (error)
        {
            return;
        }
        // 没有符合条件的频道
        if (result.channels.count <= 0)
        {
            return;
        }
        NIMQChatChannel *channel = result.channels[0];
        NIMQChatSubscribeChannelParam *subscribeChannelParam = [[NIMQChatSubscribeChannelParam alloc] init];
        subscribeChannelParam.subscribeType = NIMQChatSubscribeTypeChannelMsgUnreadCount;
        subscribeChannelParam.operationType = NIMQChatSubscribeOperationTypeSubscribe;
        subscribeChannelParam.targets = @[channel];
        [NIMSDK.sharedSDK.qchatChannelManager subscribeChannel:subscribeChannelParam completion:^(NSError *__nullable error, NIMQChatSubscribeChannelResult *__nullable result)
        {
            //your code
        }];
    }];
    

步骤2:清除未读数

以下说明以清除频道 1 的未读数为例,介绍在完成步骤1: 监听未读数后,如何清除频道未读数以及清除后对未读数进行持续监听。

  1. 进入频道 1 后,记住您应用中“代表该频道的属性”(假设为currentChannel)。

  2. 调用markMessageRead:completion:方法,调用时传ackTimestamp参数为已读的最新消息的时间戳(Unix 时间戳),进行未读数的清零操作。

    未读数清零时,SDK 触发NIMQChatUnreadInfoChangedEvent事件,该事件包含的未读数参数unreadInfo0

    • 针对同一个频道,调用 markMessageRead:completion 方法存在频控限制,300 ms 内只能调用一次。
    • 如果调用markMessageRead:completion方法时传ackTimestamp参数为0,会将频道内所有消息标记为未读。

    示例代码如下:

    id<NIMQChatMessageManager> qchatMessageManager = [[NIMSDK sharedSDK] qchatMessageManager];
    NIMQChatMarkMessageReadParam *param = [[NIMQChatMarkMessageReadParam alloc] init];
    param.serverId = 123456;
    param.channelId = 121212;
    param.ackTimestamp = 1641006661.111;
    [qchatMessageManager markMessageRead:param
            completion:^(NSError *__nullable error) {
        // your code
    }];
    
    
  3. 根据您的应用逻辑做出判断和处理:当currentChannelNIMQChatUnreadInfoChanged事件里的channelId相同时,每当频道 1 有新消息接收时,仍旧会触发该事件。

实现频道未读数的直接获取

如果您不想订阅某个频道,而只想获取该频道当前的未读数,完成以下操作即可。

  1. 确保您已在当前频道中。

  2. 直接调用getChannelUnreadInfos:completion:方法查询当前频道未读信息。

    该方法单次最多查询频道数量为 100。


    示例代码:

    objcNIMQChatChannelIdInfo *channelIdInfo = [[NIMQChatChannelIdInfo alloc] init];
    channelIdInfo.channelId = channelId;
    channelIdInfo.serverId = serverId;
    NIMQChatGetChannelUnreadInfosParam *param = [[NIMQChatGetChannelUnreadInfosParam alloc] initWithTargets:@[channelIdInfo]];
    [NIMSDK.sharedSDK.qchatChannelManager getChannelUnreadInfos:param completion:^(NSError *__nullable error, NIMQChatGetChannelUnreadInfosResult *__nullable result)
    {
        //your code
    }];
    

常见问题

1. 什么操作会导致频道未读数增加?

您当前所在的频道中,有用户发送消息或更新消息,对应频道中的当前用户未读信息中的未读数会增加。以下特殊情情况除外:

  • 消息发送者是自己
  • 不存云端消息历史
  • 不需要消息计数
  • 未订阅当前频道

2. 什么操作会导致频道未读数减少?

您当前所在的频道中,有用户删除消息,对应频道中的当前用户未读信息中的未读数会减少。以下特殊情况除外:

  • 删除的是自己发的消息,则未读数不变。
  • 不存云端消息历史
  • 不需要消息计数
  • 未订阅当前频道。

3. 撤回消息和重发消息是否影响未读数?

这两种操作都不影响未读数。

4. 通过markMessageRead:completion:方法标记频道消息已读,对未读数有什么影响?

如果在当前频道通过该方法标记消息已读,会更新对应频道的未读信息。

调用该方法时传入ackTimestamp参数(标记消息已读的时间戳),不仅可能减少未读数,还可能增加未读数。例如将ackTimestamp设为0时,会标记所有消息未读从而增加未读数。

此文档是否对你有帮助?
有帮助
去反馈
  • 未读信息定义
  • 前提条件
  • 使用限制
  • 实现流程
  • 实现频道未读数持续监听
  • 步骤1: 监听未读数
  • 步骤2:清除未读数
  • 实现频道未读数的直接获取
  • 常见问题
  • 1. 什么操作会导致频道未读数增加?
  • 2. 什么操作会导致频道未读数减少?
  • 3. 撤回消息和重发消息是否影响未读数?
  • 4. 通过markMessageRead:completion:方法标记频道消息已读,对未读数有什么影响?