tencent cloud

文档反馈

Android & iOS & Mac

最后更新时间:2023-07-17 15:12:59

    功能描述

    用户的会话列表中一般会有多个会话,如果某个会话收到了新消息,通常需要在列表的 cell 中以小红点或者数字角标的方式,向用户展示该会话的未读消息数,提醒用户阅读。 用户点击进入该会话,再退回到会话列表,未读消息数被清空,小红点消失。 IM SDK 支持获取所有会话的未读消息总数和根据过滤条件获取部分会话的未读消息总数,将其展示在会话列表的底部 tab 上。
    本文将向您介绍如何实现会话未读消息提醒功能。
    

    获取所有会话的未读消息总数

    通常情况下,如果您想得到所有会话的未读消息总数,可以遍历会话列表得到每个会话的信息 V2TIMConversation,然后再把所有的 V2TIMConversationunreadCount 相加起来,展示在 UI 上。 但 IM SDK 为您提供了直接查询所有会话未读消息总数的接口 getTotalUnreadMessageCount。 当会话的未读总数发生变更时,SDK 还会主动通过回调 onTotalUnreadMessageCountChanged,将最新的未读总数通知出来。
    说明
    1. 仅增强版 5.3.425 及以上版本,支持获取所有会话未读消息总数。
    2. 仅适用于好友工作群(Work)、陌生人社交群(Public)和社群(Community),但直播群(AVChatRoom)和临时会议群(Meeting)暂不适用。群组类型详见 群组介绍
    具体的操作步骤如下文所示:

    获取所有会话的未读总数

    您可以调用 getTotalUnreadMessageCount(Android / iOS & Mac / Windows) 获取所有会话的未读消息总数,获取成功后可以使用其更新 UI。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    V2TIMManager.getConversationManager().getTotalUnreadMessageCount(new V2TIMValueCallback<Long>() {
    @Override
    public void onSuccess(Long aLong) {
    Log.i("imsdk", "success");
    }
    
    @Override
    public void onError(int code, String desc) {
    Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
    }
    });
    [[V2TIMManager sharedInstance] getTotalUnreadMessageCount:^(UInt64 totalCount) {
    // 获取成功,totalCount 为所有会话的未读消息总数
    // 更新 UI 上的未读数
    } fail:^(int code, NSString *desc) {
    // 获取失败
    }];
    template <class T>
    class ValueCallback final : public V2TIMValueCallback<T> {
    public:
    using SuccessCallback = std::function<void(const T&)>;
    using ErrorCallback = std::function<void(int, const V2TIMString&)>;
    
    ValueCallback() = default;
    ~ValueCallback() override = default;
    
    void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
    success_callback_ = std::move(success_callback);
    error_callback_ = std::move(error_callback);
    }
    
    void OnSuccess(const T& value) override {
    if (success_callback_) {
    success_callback_(value);
    }
    }
    void OnError(int error_code, const V2TIMString& error_message) override {
    if (error_callback_) {
    error_callback_(error_code, error_message);
    }
    }
    
    private:
    SuccessCallback success_callback_;
    ErrorCallback error_callback_;
    };
    
    auto callback = new ValueCallback<uint64_t>{};
    callback->SetCallback(
    [=](const uint64_t& count) {
    // 获取所有会话的未读总数成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 获取所有会话的未读总数失败
    delete callback;
    });
    
    V2TIMManager::GetInstance()->GetConversationManager()->GetTotalUnreadMessageCount(callback);

    所有会话的未读总数变更通知

    您可以调用 addConversationListener(Android / iOS & Mac / Windows) 添加会话监听器。添加监听器后,只需要调用过一次 getTotalUnreadMessageCount 接口,才能接收到所有会话的未读总数变更通知。
    您可以在 V2TIMConversationListener 中的 onTotalUnreadMessageCountChanged(Android / iOS & Mac / Windows) 中,获取到变更后的未读总数。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    public void onTotalUnreadMessageCountChanged(long totalUnreadCount) {
    // 收到所有会话的未读总数变更通知
    Log.i("imsdk", "onTotalUnreadMessageCountChanged");
    }
    // 添加会话监听器
    [[V2TIMManager sharedInstance] addConversationListener:self];
    
    // 收到所有会话的未读总数变更通知
    - (void)onTotalUnreadMessageCountChanged:(UInt64)totalUnreadCount {
    // totalUnreadCount 为未读消息总数
    }
    class ConversationListener final : public V2TIMConversationListener {
    public:
    /**
    * 会话所有会话的未读总数变更通知(5.3.425 及以上版本支持)
    *
    * @note
    * - 未读总数会减去设置为免打扰的会话的未读数,即消息接收选项设置为
    * V2TIM_NOT_RECEIVE_MESSAGE or V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE 的会话。
    */
    void OnTotalUnreadMessageCountChanged(uint64_t totalUnreadCount) override {
    // 收到所有会话的未读总数变更通知
    }
    // 其他成员函数 ...
    };
    
    // 添加会话事件监听器,注意在移除监听器之前需要保持 conversationListener 的生命期,以免接收不到事件回调
    ConversationListener conversationListener;
    V2TIMManager::GetInstance()->GetConversationManager()->AddConversationListener(&conversationListener);
    

    根据过滤条件获取部分会话的未读消息总数

    IM SDK 为您提供了根据过滤条件查询部分会话未读消息总数的接口 getUnreadMessageCountByFilter。 如果您需要监听指定过滤条件下的会话未读消息总数变更,可以调用 subscribeUnreadMessageCountByFilter 注册监听,当该过滤条件下的会话未读消息总数发生变更时,SDK 还会主动通过回调 onUnreadMessageCountChangedByFilter,将最新的未读总数通知出来。
    说明
    1. 仅增强版 7.0.3754 及以上版本,支持根据过滤条件获取部分会话的未读消息总数。
    2. 仅适用于好友工作群(Work)、陌生人社交群(Public)和社群(Community),但直播群(AVChatRoom)和临时会议群(Meeting)暂不适用。群组类型详见 群组介绍
    您可以调用 getUnreadMessageCountByFilter(Android / iOS & Mac / Windows) 获取部分会话的未读消息总数,获取成功后可以使用其更新 UI。其中过滤条件 V2TIMConversationListFilter 详解如下:
    属性
    含义
    说明
    type
    会话类型(填 0 代表不过滤此项)
    C2C 或者群组会话
    conversationGroup
    会话分组名称(不填写代表不过滤此项)
    不是群组名称,是会话分组的名称,参考文档 会话分组
    markType
    会话标记类型(填 0 代表不过滤此项)
    参考文档 会话标记
    hasUnreadCount
    会话包含未读数
    true :返回包含未读数的会话;false:返回所有会话
    hasGroupAtInfo
    会话包含群 @ 消息
    true :返回包含群 @ 消息的会话;false:返回所有会话

    获取单聊或群聊会话的未读总数

    Android
    iOS & Mac
    Windows
    V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
    filter.setConversationType(V2TIMConversation.V2TIM_C2C); //拉取单聊会话
    // filter.setConversationType(V2TIMConversation.V2TIM_GROUP); //拉取群聊会话
    
    V2TIMManager.getConversationManager().getUnreadMessageCountByFilter(filter, new V2TIMValueCallback<Long>() {
    @Override
    public void onSuccess(Long totalUnreadCount) {
    tvLog.setText("getUnreadMessageCountByFilter success, totalUnreadCount:" + totalUnreadCount);
    }
    
    @Override
    public void onError(int code, String desc) {
    tvLog.setText("getUnreadMessageCountByFilter failed");
    }
    });
    V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
    filter.type = V2TIM_C2C; //拉取单聊会话
    // filter.type = V2TIM_GROUP; //拉取群聊会话
    
    [[V2TIMManager sharedInstance] getUnreadMessageCountByFilter:filter succ:^(UInt64 totalUnreadCount) {
    [self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter success totalUnreadCount:%llu", totalUnreadCount]];
    } fail:^(int code, NSString *desc) {
    [self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter failed"]];
    }];
    template <class T>
    class ValueCallback final : public V2TIMValueCallback<T> {
    public:
    using SuccessCallback = std::function<void(const T&)>;
    using ErrorCallback = std::function<void(int, const V2TIMString&)>;
    
    ValueCallback() = default;
    ~ValueCallback() override = default;
    
    void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
    success_callback_ = std::move(success_callback);
    error_callback_ = std::move(error_callback);
    }
    
    void OnSuccess(const T& value) override {
    if (success_callback_) {
    success_callback_(value);
    }
    }
    void OnError(int error_code, const V2TIMString& error_message) override {
    if (error_callback_) {
    error_callback_(error_code, error_message);
    }
    }
    
    private:
    SuccessCallback success_callback_;
    ErrorCallback error_callback_;
    };
    
    V2TIMConversationListFilter filter;
    filter.type = V2TIM_C2C; // 拉取单聊会话
    // filter.type = V2TIM_GROUP; // 拉取群聊会话
    auto callback = new ValueCallback<uint64_t>{};
    callback->SetCallback(
    [=](const uint64_t& count) {
    // 获取部分会话的未读总数成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 获取部分会话的未读总数失败
    delete callback;
    });
    V2TIMManager::GetInstance()->GetConversationManager()->GetUnreadMessageCountByFilter(filter, callback);

    获取指定分组会话的未读总数

    Android
    iOS & Mac
    Windows
    V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
    filter.setConversationGroup("conversation_group");
    
    V2TIMManager.getConversationManager().getUnreadMessageCountByFilter(filter, new V2TIMValueCallback<Long>() {
    @Override
    public void onSuccess(Long totalUnreadCount) {
    tvLog.setText("getUnreadMessageCountByFilter success, totalUnreadCount:" + totalUnreadCount);
    }
    
    @Override
    public void onError(int code, String desc) {
    tvLog.setText("getUnreadMessageCountByFilter failed");
    }
    });
    V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
    filter.conversationGroup = @"conversation_group";
    
    [[V2TIMManager sharedInstance] getUnreadMessageCountByFilter:filter succ:^(UInt64 totalUnreadCount) {
    [self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter success totalUnreadCount:%llu", totalUnreadCount]];
    } fail:^(int code, NSString *desc) {
    [self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter failed"]];
    }];
    template <class T>
    class ValueCallback final : public V2TIMValueCallback<T> {
    public:
    using SuccessCallback = std::function<void(const T&)>;
    using ErrorCallback = std::function<void(int, const V2TIMString&)>;
    
    ValueCallback() = default;
    ~ValueCallback() override = default;
    
    void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
    success_callback_ = std::move(success_callback);
    error_callback_ = std::move(error_callback);
    }
    
    void OnSuccess(const T& value) override {
    if (success_callback_) {
    success_callback_(value);
    }
    }
    void OnError(int error_code, const V2TIMString& error_message) override {
    if (error_callback_) {
    error_callback_(error_code, error_message);
    }
    }
    
    private:
    SuccessCallback success_callback_;
    ErrorCallback error_callback_;
    };
    
    V2TIMConversationListFilter filter;
    filter.conversationGroup = "conversation_group";
    auto callback = new ValueCallback<uint64_t>{};
    callback->SetCallback(
    [=](const uint64_t& count) {
    // 获取部分会话的未读总数成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 获取部分会话的未读总数失败
    delete callback;
    });
    V2TIMManager::GetInstance()->GetConversationManager()->GetUnreadMessageCountByFilter(filter, callback);

    获取指定标记会话的未读总数

    Android
    iOS & Mac
    Windows
    V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
    filter.setMarkType(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_STAR);
    
    V2TIMManager.getConversationManager().getUnreadMessageCountByFilter(filter, new V2TIMValueCallback<Long>() {
    @Override
    public void onSuccess(Long totalUnreadCount) {
    tvLog.setText("getUnreadMessageCountByFilter success, totalUnreadCount:" + totalUnreadCount);
    }
    
    @Override
    public void onError(int code, String desc) {
    tvLog.setText("getUnreadMessageCountByFilter failed");
    }
    });
    V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
    filter.markType = V2TIM_CONVERSATION_MARK_TYPE_STAR;
    
    [[V2TIMManager sharedInstance] getUnreadMessageCountByFilter:filter succ:^(UInt64 totalUnreadCount) {
    [self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter success totalUnreadCount:%llu", totalUnreadCount]];
    } fail:^(int code, NSString *desc) {
    [self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter failed"]];
    }];
    template <class T>
    class ValueCallback final : public V2TIMValueCallback<T> {
    public:
    using SuccessCallback = std::function<void(const T&)>;
    using ErrorCallback = std::function<void(int, const V2TIMString&)>;
    
    ValueCallback() = default;
    ~ValueCallback() override = default;
    
    void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
    success_callback_ = std::move(success_callback);
    error_callback_ = std::move(error_callback);
    }
    
    void OnSuccess(const T& value) override {
    if (success_callback_) {
    success_callback_(value);
    }
    }
    void OnError(int error_code, const V2TIMString& error_message) override {
    if (error_callback_) {
    error_callback_(error_code, error_message);
    }
    }
    
    private:
    SuccessCallback success_callback_;
    ErrorCallback error_callback_;
    };
    
    V2TIMConversationListFilter filter;
    filter.markType = V2TIM_CONVERSATION_MARK_TYPE_STAR;
    auto callback = new ValueCallback<uint64_t>{};
    callback->SetCallback(
    [=](const uint64_t& count) {
    // 获取部分会话的未读总数成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 获取部分会话的未读总数失败
    delete callback;
    });
    V2TIMManager::GetInstance()->GetConversationManager()->GetUnreadMessageCountByFilter(filter, callback);

    获取含有未读数会话的未读总数

    Android
    iOS & Mac
    Windows
    V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
    filter.setHasUnreadCount(true);
    
    V2TIMManager.getConversationManager().getUnreadMessageCountByFilter(filter, new V2TIMValueCallback<Long>() {
    @Override
    public void onSuccess(Long totalUnreadCount) {
    tvLog.setText("getUnreadMessageCountByFilter success, totalUnreadCount:" + totalUnreadCount);
    }
    
    @Override
    public void onError(int code, String desc) {
    tvLog.setText("getUnreadMessageCountByFilter failed");
    }
    });
    V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
    filter.hasUnreadCount = YES;
    
    [[V2TIMManager sharedInstance] getUnreadMessageCountByFilter:filter succ:^(UInt64 totalUnreadCount) {
    [self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter success totalUnreadCount:%llu", totalUnreadCount]];
    } fail:^(int code, NSString *desc) {
    [self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter failed"]];
    }];
    template <class T>
    class ValueCallback final : public V2TIMValueCallback<T> {
    public:
    using SuccessCallback = std::function<void(const T&)>;
    using ErrorCallback = std::function<void(int, const V2TIMString&)>;
    
    ValueCallback() = default;
    ~ValueCallback() override = default;
    
    void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
    success_callback_ = std::move(success_callback);
    error_callback_ = std::move(error_callback);
    }
    
    void OnSuccess(const T& value) override {
    if (success_callback_) {
    success_callback_(value);
    }
    }
    void OnError(int error_code, const V2TIMString& error_message) override {
    if (error_callback_) {
    error_callback_(error_code, error_message);
    }
    }
    
    private:
    SuccessCallback success_callback_;
    ErrorCallback error_callback_;
    };
    
    V2TIMConversationListFilter filter;
    filter.hasUnreadCount = true;
    auto callback = new ValueCallback<uint64_t>{};
    callback->SetCallback(
    [=](const uint64_t& count) {
    // 获取部分会话的未读总数成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 获取部分会话的未读总数失败
    delete callback;
    });
    V2TIMManager::GetInstance()->GetConversationManager()->GetUnreadMessageCountByFilter(filter, callback);

    获取含有群 @ 消息会话的未读数

    Android
    iOS & Mac
    Windows
    V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
    filter.setHasGroupAtInfo(true);
    
    V2TIMManager.getConversationManager().getUnreadMessageCountByFilter(filter, new V2TIMValueCallback<Long>() {
    @Override
    public void onSuccess(Long totalUnreadCount) {
    tvLog.setText("getUnreadMessageCountByFilter success, totalUnreadCount:" + totalUnreadCount);
    }
    
    @Override
    public void onError(int code, String desc) {
    tvLog.setText("getUnreadMessageCountByFilter failed");
    }
    });
    V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
    filter.hasGroupAtInfo = YES;
    
    [[V2TIMManager sharedInstance] getUnreadMessageCountByFilter:filter succ:^(UInt64 totalUnreadCount) {
    [self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter success totalUnreadCount:%llu", totalUnreadCount]];
    } fail:^(int code, NSString *desc) {
    [self appendString:[NSString stringWithFormat:@"getUnreadMessageCountByFilter failed"]];
    }];
    template <class T>
    class ValueCallback final : public V2TIMValueCallback<T> {
    public:
    using SuccessCallback = std::function<void(const T&)>;
    using ErrorCallback = std::function<void(int, const V2TIMString&)>;
    
    ValueCallback() = default;
    ~ValueCallback() override = default;
    
    void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
    success_callback_ = std::move(success_callback);
    error_callback_ = std::move(error_callback);
    }
    
    void OnSuccess(const T& value) override {
    if (success_callback_) {
    success_callback_(value);
    }
    }
    void OnError(int error_code, const V2TIMString& error_message) override {
    if (error_callback_) {
    error_callback_(error_code, error_message);
    }
    }
    
    private:
    SuccessCallback success_callback_;
    ErrorCallback error_callback_;
    };
    
    V2TIMConversationListFilter filter;
    filter.hasGroupAtInfo = true;
    auto callback = new ValueCallback<uint64_t>{};
    callback->SetCallback(
    [=](const uint64_t& count) {
    // 获取部分会话的未读总数成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 获取部分会话的未读总数失败
    delete callback;
    });
    V2TIMManager::GetInstance()->GetConversationManager()->GetUnreadMessageCountByFilter(filter, callback);

    注册监听部分会话的未读消息总数变更

    您可以调用 addConversationListener(Android / iOS & Mac / Windows) 添加会话监听器。添加监听器后,需要您调用 subscribeUnreadMessageCountByFilter(Android / iOS & Mac / Windows) 接口,注册监听指定过滤条件下的未读消息总数变更。
    您可以在 V2TIMConversationListener 中的 onUnreadMessageCountChangedByFilter(Android / iOS & Mac / Windows) 中,获取到变更后的未读总数。
    您可以注册监听多个不同过滤条件下的未读总数变更,onUnreadMessageCountChangedByFilter 回调的 filter 参数就是调用 subscribeUnreadMessageCountByFilter 时指定的 filter,该 filter 携带了 conversationType、conversationGroup 和 markType 三个字段,通过判断这三字段是不是都相同,来区分出不同的过滤条件。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    // 添加会话监听器
    V2TIMManager.getConversationManager().addConversationListener(conversationListener);
    
    // 注册监听指定过滤条件下的未读消息总数变更
    V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
    filter.setConversationType(V2TIMConversation.V2TIM_GROUP);
    filter.setConversationGroup("conversation_group");
    filter.setMarkType(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_STAR);
    V2TIMManager.getConversationManager().subscribeUnreadMessageCountByFilter(filter);
    
    // 指定过滤条件下的未读消息总数变更通知
    public void onUnreadMessageCountChangedByFilter(V2TIMConversationListFilter filter, long totalUnreadCount) {
    // filter 是过滤条件,totalUnreadCount 是未读消息总数
    Log.i(TAG, "onUnreadMessageCountChangedByFilter:" + totalUnreadCount + "\\n");
    }
    // 添加会话监听器
    [[V2TIMManager sharedInstance] addConversationListener:self];
    
    // 注册监听指定过滤条件下的未读消息总数变更
    V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
    filter.type = V2TIM_GROUP;
    filter.conversationGroup = @"conversation_group";
    filter.markType = V2TIM_CONVERSATION_MARK_TYPE_STAR;
    [[V2TIMManager sharedInstance] subscribeUnreadMessageCountByFilter:filter];
    
    // 指定过滤条件下的未读消息总数变更通知
    - (void)onUnreadMessageCountChangedByFilter:(V2TIMConversationListFilter *)filter totalUnreadCount:(UInt64)totalUnreadCount {
    // filter 是过滤条件,totalUnreadCount 是未读消息总数
    }
    class ConversationListener final : public V2TIMConversationListener {
    public:
    // 指定过滤条件下的未读消息总数变更通知
    void OnUnreadMessageCountChangedByFilter(const V2TIMConversationListFilter &filter, uint64_t totalUnreadCount) override {
    // filter 是过滤条件,totalUnreadCount 是未读消息总数
    }
    // 其他成员函数 ...
    };
    
    // 添加会话事件监听器,注意在移除监听器之前需要保持 conversationListener 的生命期,以免接收不到事件回调
    ConversationListener conversationListener;
    V2TIMManager::GetInstance()->GetConversationManager()->AddConversationListener(&conversationListener);
    
    // 注册监听指定过滤条件下的未读消息总数变更
    V2TIMConversationListFilter filter;
    filter.type = V2TIM_GROUP;
    filter.conversationGroup = "conversation_group";
    filter.markType = V2TIM_CONVERSATION_MARK_TYPE_STAR;
    V2TIMManager::GetInstance()->GetConversationManager()->SubscribeUnreadMessageCountByFilter(filter);

    取消监听部分会话的未读消息总数变更

    您可以调用 unsubscribeUnreadMessageCountByFilter(Android / iOS & Mac / Windows) 接口,取消监听指定过滤条件下的未读消息总数变更。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    // 取消监听指定过滤条件下的未读消息总数变更
    V2TIMConversationListFilter filter = new V2TIMConversationListFilter();
    filter.setConversationType(V2TIMConversation.V2TIM_GROUP);
    filter.setConversationGroup("conversation_group");
    filter.setMarkType(V2TIMConversation.V2TIM_CONVERSATION_MARK_TYPE_STAR);
    V2TIMManager.getConversationManager().unsubscribeUnreadMessageCountByFilter(filter);
    // 取消监听指定过滤条件下的未读消息总数变更
    V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
    filter.type = V2TIM_GROUP;
    filter.conversationGroup = @"conversation_group";
    filter.markType = V2TIM_CONVERSATION_MARK_TYPE_STAR;
    [[V2TIMManager sharedInstance] unsubscribeUnreadMessageCountByFilter:filter];
    // 取消监听指定过滤条件下的未读消息总数变更
    V2TIMConversationListFilter filter;
    filter.type = V2TIM_GROUP;
    filter.conversationGroup = "conversation_group";
    filter.markType = V2TIM_CONVERSATION_MARK_TYPE_STAR;
    V2TIMManager::GetInstance()->GetConversationManager()->UnsubscribeUnreadMessageCountByFilter(filter);

    清理会话未读消息数

    用户点击进入会话后,再退回到会话列表,需要清理未读消息数。若未读数被清 0 ,则会话列表的小红点或数字角标需要随之消失。 您可以调用 cleanConversationUnreadMessageCountAndroid / iOS & Mac / Windows)来清理指定会话未读消息数,通过传入特定格式的参数可以分别完成对指定单聊会话全部单聊会话指定群聊会话全部群聊会话以及全部会话未读消息数的清理,具体的操作步骤如下文所示。
    说明
    清理会话未读消息数功能仅增强版 7.1.3925 及以上版本支持。
    接口说明如下:
    Android
    iOS & Mac
    Windows
    方法原型:
    // V2TIMConversationManager
    public abstract void cleanConversationUnreadMessageCount(String conversationID, long cleanTimestamp,
    long cleanSequence, V2TIMCallback callback);
    参数说明:
    参数
    含义
    单聊有效
    群聊有效
    说明
    conversationID
    会话唯一 ID
    YES
    YES
    C2C 单聊组成方式为: String.format("c2c_%s", "userID");群聊组成方式为: String.format("group_%s", "groupID")。
    cleanTimestamp
    清理时间戳,单位为秒
    YES
    NO
    指定清理哪一个 timestamp 之前的未读消息计数;当传入为 0 时,对应会话所有的未读消息将被清理,会话的未读数会清 0。
    cleanSequence
    清理 sequence
    NO
    YES
    指定清理哪一个 sequence 之前的未读消息计数;当传入为 0 时,对应会话所有的未读消息将被清理,会话的未读数会清 0。
    callback
    清理会话未读数结果回调
    YES
    YES
    接口调用成功与否的回调。
    
    方法原型:
    // V2TIMManager+Conversation.h
    - (void)cleanConversationUnreadMessageCount:(NSString *)conversationID
    cleanTimestamp:(uint64_t)cleanTimestamp
    cleanSequence:(uint64_t)cleanSequence
    succ:(V2TIMSucc)succ
    fail:(V2TIMFail)fail;
    参数说明:
    参数
    含义
    单聊有效
    群聊有效
    说明
    conversationID
    会话唯一 ID
    YES
    YES
    C2C 单聊组成方式:[NSString stringWithFormat:@"c2c_%@",userID];群聊组成方式为 [NSString stringWithFormat:@"group_%@",groupID]。
    cleanTimestamp
    清理时间戳
    YES
    NO
    指定清理哪一个 timestamp 之前的未读消息计数;当传入为 0 时,对应会话所有的未读消息将被清理,会话的未读数会清 0。
    cleanSequence
    清理 sequence
    NO
    YES
    指定清理哪一个 sequence 之前的未读消息计数;当传入为 0 时,对应会话所有的未读消息将被清理,会话的未读数会清 0。
    succ
    清理会话未读数结果成功回调
    YES
    YES
    ——
    fail
    消息发送失败回调
    YES
    YES
    回调失败错误码、错误描述。
    
    方法原型:
    // V2TIMConversationManager
    virtual void CleanConversationUnreadMessageCount(
    const V2TIMString& conversationID,
    uint64_t cleanTimestamp,
    uint64_t cleanSequence,
    V2TIMCallback* callback);
    参数说明:
    参数
    含义
    单聊有效
    群聊有效
    说明
    conversationID
    会话唯一 ID
    YES
    YES
    C2C 单聊组成方式为: "c2c_userID";群聊组成方式为: "group_groupID"
    cleanTimestamp
    清理时间戳
    YES
    NO
    指定清理哪一个 timestamp 之前的未读消息计数;当传入为 0 时,对应会话所有的未读消息将被清理,会话的未读数会清 0。
    cleanSequence
    清理 sequence
    NO
    YES
    指定清理哪一个 sequence 之前的未读消息计数;当传入为 0 时,对应会话所有的未读消息将被清理,会话的未读数会清 0。
    callback
    清理会话未读数结果回调
    YES
    YES
    接口调用成功与否的回调。
    
    说明:
    当您想清理所有单聊会话的未读消息计数,conversationID 请传入 "c2c",即不指定具体的 userID;
    当您想清理所有群聊会话的未读消息计数,conversationID 请传入 "group",即不指定具体的 groupID;
    当您想清理所有会话的未读消息计数,conversationID 请传入 "";
    该接口调用成功后,SDK 会通过 onConversationChanged 回调将对应会话的最新未读数通知给您。

    清理指定单聊会话的未读数

    您可以通过传入带有 "c2c_" 前缀的 conversationID 来清理指定单聊会话未读消息数,同时还可以通过传入 cleanTimestamp 来清理指定时间戳及其之前的未读消息数。如果传入的 cleanTimestamp 为 0,则将指定单聊会话的未读数清 0。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    String conversationID = "c2c_userID";
    V2TIMManager.getConversationManager().cleanConversationUnreadMessageCount(conversationID, 123456, 0, new V2TIMCallback() {
    @Override
    public void onSuccess() {
    Log.i("imsdk", "success");
    }
    
    @Override
    public void onError(int code, String desc) {
    Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
    }
    });
    [[V2TIMManager sharedInstance] cleanConversationUnreadMessageCount:@"c2c_userID"
    cleanTimestamp:123456
    cleanSequence:0
    succ:^{
    // 清理指定单聊会话未读数成功
    } fail:^(int code, NSString *msg) {
    // 清理指定单聊会话未读数失败
    }];
    class Callback final : public V2TIMCallback {
    public:
    using SuccessCallback = std::function<void()>;
    using ErrorCallback = std::function<void(int, const V2TIMString&)>;
    
    Callback() = default;
    ~Callback() override = default;
    
    void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
    success_callback_ = std::move(success_callback);
    error_callback_ = std::move(error_callback);
    }
    
    void OnSuccess() override {
    if (success_callback_) {
    success_callback_();
    }
    }
    void OnError(int error_code, const V2TIMString& error_message) override {
    if (error_callback_) {
    error_callback_(error_code, error_message);
    }
    }
    
    private:
    SuccessCallback success_callback_;
    ErrorCallback error_callback_;
    };
    
    V2TIMString conversationID = u8"c2c_userID";
    
    auto callback = new Callback;
    callback->SetCallback(
    [=]() {
    // 清理指定单聊会话未读数成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 清理指定单聊会话未读数失败
    delete callback;
    });
    
    V2TIMManager::GetInstance()->GetConversationManager()->CleanConversationUnreadMessageCount(conversationID, 123456, 0, callback);
    当本端调用 cleanConversationUnreadMessageCount 成功后,如果调用者事先调用 addConversationListener 添加了会话监听器,会收到 onConversationChanged 回调,该回调中携带了对应会话的最新未读消息数,可以在此回调中更新 UI。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    public void onConversationChanged(List<V2TIMConversation> conversationList) {
    // 调用者收到会话信息变更通知
    Log.i("imsdk", "onConversationChanged");
    }
    // 添加会话监听器
    [[V2TIMManager sharedInstance] addConversationListener:self];
    
    // 调用者收到会话信息变更通知
    - (void)onConversationChanged:(NSArray<V2TIMConversation*> *)conversationList {
    // 根据 conversationList 中的 V2TIMConversation 更新对应 UI
    }
    class ConversationListener final : public V2TIMConversationListener {
    public:
    /**
    * 某些会话的关键信息发生变化(未读计数发生变化、最后一条消息被更新等等),可以根据会话的
    * lastMessage -> timestamp 重新对会话列表做排序
    *
    * @param conversationList 会话列表
    */
    void OnConversationChanged(const V2TIMConversationVector& conversationList) override {}
    // 其他成员 ...
    };
    
    // 添加会话事件监听器,注意在移除监听器之前需要保持 conversationListener 的生命期,以免接收不到事件回调
    ConversationListener conversationListener;
    V2TIMManager::GetInstance()->GetConversationManager()->AddConversationListener(&conversationListener);

    清空所有单聊会话的未读数

    您可以传入 "c2c" 作为 conversationID,表示将所有单聊会话的未读数全部清 0,请注意此时 cleanTimestamp 将不再生效。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    String conversationID = "c2c";
    V2TIMManager.getConversationManager().cleanConversationUnreadMessageCount(conversationID, 0, 0, new V2TIMCallback() {
    @Override
    public void onSuccess() {
    Log.i("imsdk", "success");
    }
    
    @Override
    public void onError(int code, String desc) {
    Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
    }
    });
    [[V2TIMManager sharedInstance] cleanConversationUnreadMessageCount:@"c2c"
    cleanTimestamp:0
    cleanSequence:0
    succ:^{
    // 清空所有单聊会话未读消息数成功
    } fail:^(int code, NSString *msg) {
    // 清空所有单聊会话未读消息数失败
    }];
    class Callback final : public V2TIMCallback {
    public:
    using SuccessCallback = std::function<void()>;
    using ErrorCallback = std::function<void(int, const V2TIMString&)>;
    
    Callback() = default;
    ~Callback() override = default;
    
    void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
    success_callback_ = std::move(success_callback);
    error_callback_ = std::move(error_callback);
    }
    
    void OnSuccess() override {
    if (success_callback_) {
    success_callback_();
    }
    }
    void OnError(int error_code, const V2TIMString& error_message) override {
    if (error_callback_) {
    error_callback_(error_code, error_message);
    }
    }
    
    private:
    SuccessCallback success_callback_;
    ErrorCallback error_callback_;
    };
    
    V2TIMString conversationID = u8"c2c";
    
    auto callback = new Callback;
    callback->SetCallback(
    [=]() {
    // 清空所有单聊会话未读消息数成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 清空所有单聊会话未读消息数失败
    delete callback;
    });
    
    V2TIMManager::GetInstance()->GetConversationManager()->CleanConversationUnreadMessageCount(conversationID, 0, 0, callback);
    当本端调用 cleanConversationUnreadMessageCount 成功后,如果调用者事先调用 addConversationListener 添加了会话监听器,会收到 onConversationChanged 回调,该回调中携带了对应会话的最新未读消息数,可以在此回调中更新 UI。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    public void onConversationChanged(List<V2TIMConversation> conversationList) {
    // 调用者收到会话信息变更通知
    Log.i("imsdk", "onConversationChanged");
    }
    // 添加会话监听器
    [[V2TIMManager sharedInstance] addConversationListener:self];
    
    // 调用者收到会话信息变更通知
    - (void)onConversationChanged:(NSArray<V2TIMConversation*> *)conversationList {
    // 根据 conversationList 中的 V2TIMConversation 更新对应 UI,例如清除掉单聊会话 cell 小红点
    }
    class ConversationListener final : public V2TIMConversationListener {
    public:
    /**
    * 某些会话的关键信息发生变化(未读计数发生变化、最后一条消息被更新等等),可以根据会话的
    * lastMessage -> timestamp 重新对会话列表做排序
    *
    * @param conversationList 会话列表
    */
    void OnConversationChanged(const V2TIMConversationVector& conversationList) override {}
    // 其他成员 ...
    };
    
    // 添加会话事件监听器,注意在移除监听器之前需要保持 conversationListener 的生命期,以免接收不到事件回调
    ConversationListener conversationListener;
    V2TIMManager::GetInstance()->GetConversationManager()->AddConversationListener(&conversationListener);

    清理指定群聊会话的未读数

    您可以通过传入带有 "group_" 前缀的 conversationID 来清理指定群聊会话未读消息数,同时还可以通过传入 cleanSequence 来清理指定 sequence 及其之前的未读消息数。如果传入的 cleanSequence 为 0,则将指定群聊会话的未读数清 0。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    String conversationID = "group_groupID";
    V2TIMManager.getConversationManager().cleanConversationUnreadMessageCount(conversationID, 0, 123, new V2TIMCallback() {
    @Override
    public void onSuccess() {
    Log.i("imsdk", "success");
    }
    
    @Override
    public void onError(int code, String desc) {
    Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
    }
    });
    [[V2TIMManager sharedInstance] cleanConversationUnreadMessageCount:@"group_groupID"
    cleanTimestamp:0
    cleanSequence:123
    succ:^{
    // 清理指定群聊会话未读消息数成功
    } fail:^(int code, NSString *msg) {
    // 清理指定群聊会话未读消息数失败
    }];
    class Callback final : public V2TIMCallback {
    public:
    using SuccessCallback = std::function<void()>;
    using ErrorCallback = std::function<void(int, const V2TIMString&)>;
    
    Callback() = default;
    ~Callback() override = default;
    
    void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
    success_callback_ = std::move(success_callback);
    error_callback_ = std::move(error_callback);
    }
    
    void OnSuccess() override {
    if (success_callback_) {
    success_callback_();
    }
    }
    void OnError(int error_code, const V2TIMString& error_message) override {
    if (error_callback_) {
    error_callback_(error_code, error_message);
    }
    }
    
    private:
    SuccessCallback success_callback_;
    ErrorCallback error_callback_;
    };
    
    V2TIMString conversationID = u8"group_groupID";
    
    auto callback = new Callback;
    callback->SetCallback(
    [=]() {
    // 清理指定群聊会话未读消息数成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 清理指定群聊会话未读消息数失败
    delete callback;
    });
    
    V2TIMManager::GetInstance()->GetConversationManager()->CleanConversationUnreadMessageCount(conversationID, 0, 123, callback);
    当 cleanConversationUnreadMessageCount 调用成功后,如果调用者事先调用 addConversationListener 添加了会话监听器,会收到 onConversationChanged 回调,该回调中携带了对应会话的最新未读消息数,可以在此回调中更新 UI。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    public void onConversationChanged(List<V2TIMConversation> conversationList) {
    // 调用者收到会话信息变更通知
    Log.i("imsdk", "onConversationChanged");
    }
    // 添加会话监听器
    [[V2TIMManager sharedInstance] addConversationListener:self];
    
    // 调用者收到会话信息变更通知
    - (void)onConversationChanged:(NSArray<V2TIMConversation*> *)conversationList {
    // 根据 conversationList 中的 V2TIMConversation 更新对应 UI
    }
    class ConversationListener final : public V2TIMConversationListener {
    public:
    void OnConversationChanged(const V2TIMConversationVector& conversationList) override {}
    // 调用者收到会话信息变更通知</