tencent cloud

文档反馈

Android&iOS&Windows&Mac

最后更新时间:2024-07-05 18:03:10

    功能描述

    群组管理功能指的是创建群组、加入群组、获取已加入的群组、退出群组和解散群组等。

    群事件监听

    下文描述的群组管理功能中,有些会触发群事件通知回调,例如有人进群、有人退群等,这些事件都是由服务器自动触发的。
    您可以调用 addGroupListener (Android / iOS & Mac / Windows) 添加群事件监听器。
    群事件定义在 V2TIMGroupListener(Android / iOS & Mac / Windows) 中,包含群成员相关通知、群生命周期相关通知、加群申请相关通知、话题事件监听回调等。
    不想再接收群事件时,可调用 removeGroupListener (Android / iOS & Mac / Windows) 移除群事件监听器。
    如果您设置了群事件监听器,但是并没有接收到预期的事件,可以登录控制台检查 Group system notification configuration,配置页面如下所示:
    
    
    
    注意:
    直播群(AVChatRoom)不支持配置群成员变更通知、群资料变更通知。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    V2TIMGroupListener groupListener = new V2TIMGroupListener() {
    // 群成员相关通知、群生命周期相关通知、加群申请相关通知、话题事件监听回调等,不一一列举
    @Override
    public void onMemberEnter(String groupID, List<V2TIMGroupMemberInfo> memberList) {
    // 有新成员加入群,该群所有的成员都能收到
    }
    @Override
    void onMemberLeave(String groupID, V2TIMGroupMemberInfo member) {
    // 有成员离开群,该群所有的成员都能收到
    }
    
    @Override
    public void onReceiveRESTCustomData(String groupID, byte[] customData) {
    // 服务器发送的自定义系统通知
    }
    };
    
    V2TIMManager.getInstance().addGroupListener(groupListener);
    [[V2TIMManager sharedInstance] addGroupListener:self];
    
    // 群成员相关通知、群生命周期相关通知、加群申请相关通知、话题事件监听回调等,不一一列举
    - (void)onMemberEnter:(NSString *)groupID memberList:(NSArray<V2TIMGroupMemberInfo *>*)memberList {
    // 有新成员加入群,该群所有的成员都能收到
    }
    
    - (void)onMemberLeave:(NSString *)groupID member:(V2TIMGroupMemberInfo *)member {
    // 有成员离开群,该群所有的成员都能收到
    }
    
    - (void)onReceiveRESTCustomData:(NSString *)groupID data:(NSData *)data {
    // 服务器发送的自定义系统通知
    }
    class GroupListener final : public V2TIMGroupListener {
    public:
    GroupListener() = default;
    ~GroupListener() override = default;
    
    // 群成员相关通知、群生命周期相关通知、加群申请相关通知、话题事件监听回调等,不一一列举
    
    void OnMemberEnter(const V2TIMString& groupID, const V2TIMGroupMemberInfoVector& memberList) override {
    // 有新成员加入群,该群所有的成员都能收到
    }
    
    void OnMemberLeave(const V2TIMString& groupID, const V2TIMGroupMemberInfo& member) override {
    // 有成员离开群,该群所有的成员都能收到
    }
    
    void OnReceiveRESTCustomData(const V2TIMString& groupID, const V2TIMBuffer& customData) override {
    // 服务器发送的自定义系统通知
    }
    };
    
    // 添加群事件监听器,注意在移除监听器之前需要保持 groupListener 的生命期,以免接收不到事件回调
    GroupListener groupListener;
    V2TIMManager::GetInstance()->AddGroupListener(&groupListener);

    搜索群组

    您只能搜索本地存储过的群组,例如已加入的群组列表,拉取过的群组资料等。
    您可以调用接口 searchGroups (Android / iOS & Mac / Windows) 搜索本地群组。 您可以设置搜索关键字 keywordList,并指定搜索的范围,即是否搜索群组的 userIDgroupName 字段。
    说明:
    本地群组搜索功能仅 5.4.666 及以上版本支持。
    本地群组搜索为进阶版功能,购买进阶版后可使用。
    搜索关键字列表,最多支持5个。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    V2TIMGroupSearchParam searchParam = new V2TIMGroupSearchParam();
    searchParam.setKeywordList(Arrays.asList("keyword1", "keyword2", "keyword3")); // 设置搜索关键字列表,最多支持5个。
    searchParam.setSearchGroupID(true); // 设置是否搜索群 ID
    searchParam.setSearchGroupName(true); // 设置是否搜索群名称
    V2TIMManager.getGroupManager().searchGroups(searchParam, new V2TIMValueCallback<List<V2TIMGroupInfo>>() {
    @Override
    public void onSuccess(List<V2TIMGroupInfo> groupInfoList) {
    // 搜索群资料成功
    }
    
    @Override
    public void onError(int code, String desc) {
    // 搜索群资料失败
    }
    });
    V2TIMGroupSearchParam *searchParam = [[V2TIMGroupSearchParam alloc] init];
    searchParam.keywordList = @[@"keyword1", @"keyword2", @"keyword3"];
    searchParam.isSearchGroupID = true;
    searchParam.isSearchGroupName = true;
    // 搜索群资料
    [[V2TIMManager sharedInstance] searchGroups:searchParam succ:^(NSArray<V2TIMGroupInfo *> *groupList) {
    // 搜索群资料成功
    } 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_;
    };
    
    V2TIMGroupSearchParam searchParam;
    searchParam.keywordList = keywordList;
    searchParam.isSearchGroupID = true;
    searchParam.isSearchGroupName = true;
    
    auto callback = new ValueCallback<V2TIMGroupInfoVector>{};
    callback->SetCallback(
    [=](const V2TIMGroupInfoVector& groupInfoList) {
    // 搜索群组成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 搜索群组失败
    delete callback;
    });
    
    V2TIMManager::GetInstance()->GetGroupManager()->SearchGroups(searchParam, callback);

    创建群组

    普通接口

    您可以调用普通接口 createGroup (Android / iOS & Mac / Windows) 接口,并指定参数,即可创建一个群组。
    createGroup 参数说明如下表所示:
    参数
    含义
    是否必填
    说明
    groupType
    群类型
    YES
    参考 群类型介绍
    groupID
    群 ID
    NO
    如果传空,群创建成功后会自动分配。
    支持自定义群 ID,参考 自定义群组 ID 规则。
    groupName
    群名称
    YES
    最长 30 字节。
    如果您按照上文 群事件监听 中所述调用 addGroupListener 添加了群组事件监听器,群创建成功后会回调 onGroupCreated (Android / iOS & Mac / Windows) 接口。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    V2TIMManager.getInstance().createGroup(V2TIMManager.GROUP_TYPE_WORK, null, "groupA", new V2TIMValueCallback<String>() {
    @Override
    public void onSuccess(String s) {
    // 创建群组成功
    }
    
    @Override
    public void onError(int code, String desc) {
    // 创建群组失败
    }
    });
    // 监听群组创建通知
    V2TIMManager.getInstance().addGroupListener(new V2TIMGroupListener() {
    @Override
    public void onGroupCreated(String groupID) {
    // 群创建回调,groupID 为新创建群组的 ID
    }
    });
    // 创建群组
    [[V2TIMManager sharedInstance] createGroup:GroupType_Work groupID:nil groupName:@"groupA" succ:^(NSString *groupID) {
    // 创建群组成功
    } fail:^(int code, NSString *desc) {
    // 创建群组失败
    }];
    
    // 监听群组创建通知
    [[V2TIMManager sharedInstance] addGroupListener:self];
    - (void)onGroupCreated:(NSString *)groupID {
    // 群创建回调,groupID 为新创建群组的 ID
    }
    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<V2TIMString>{};
    callback->SetCallback(
    [=](const V2TIMString& string) {
    // 创建群组成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 创建群组失败
    delete callback;
    });
    
    V2TIMManager::GetInstance()->CreateGroup("Work", {}, "groupA", callback);
    
    // 监听群组创建通知
    class GroupListener final : public V2TIMGroupListener {
    public:
    GroupListener() = default;
    ~GroupListener() override = default;
    
    void OnGroupCreated(const V2TIMString& groupID) override {
    // 群创建回调,groupID 为新创建群组的 ID
    }
    // 其他成员 ...
    };
    // 添加群事件监听器,注意在移除监听器之前需要保持 groupListener 的生命期,以免接收不到事件回调
    GroupListener groupListener;
    V2TIMManager::GetInstance()->AddGroupListener(&groupListener);

    高级接口

    如果您想在创建群组的同时初始化群的信息,例如群简介、群头像、以及最初的几个群成员等,可以调用高级接口 createGroup (Android / iOS & Mac / Windows) 实现。创建成功的回调中会抛出 groupID
    示例代码如下:
    Android
    iOS & Mac
    Windows
    // 使用高级版 createGroup 创建一个工作群
    V2TIMGroupInfo v2TIMGroupInfo = new V2TIMGroupInfo();
    v2TIMGroupInfo.setGroupName("testWork");
    v2TIMGroupInfo.setGroupType("Work");
    v2TIMGroupInfo.setIntroduction("this is a test Work group");
    
    List<V2TIMCreateGroupMemberInfo> memberInfoList = new ArrayList<>();
    V2TIMCreateGroupMemberInfo memberA = new V2TIMCreateGroupMemberInfo();
    memberA.setUserID("vinson");
    V2TIMCreateGroupMemberInfo memberB = new V2TIMCreateGroupMemberInfo();
    memberB.setUserID("park");
    memberInfoList.add(memberA);
    memberInfoList.add(memberB);
    
    V2TIMManager.getGroupManager().createGroup(
    v2TIMGroupInfo, memberInfoList, new V2TIMValueCallback<String>() {
    @Override
    public void onError(int code, String desc) {
    // 创建失败
    }
    @Override
    public void onSuccess(String groupID) {
    // 创建成功
    }
    });
    // 使用高级版 createGroup 创建一个工作群
    V2TIMGroupInfo *info = [[V2TIMGroupInfo alloc] init];
    info.groupName = @"testWork";
    info.groupType = @"Work";
    NSMutableArray *memberList = [NSMutableArray array];
    V2TIMCreateGroupMemberInfo *memberInfo = [[V2TIMCreateGroupMemberInfo alloc] init];
    memberInfo.userID = @"vinson";
    [memberList addObject:memberInfo];
    [[V2TIMManager sharedInstance] createGroup:info memberList:memberList succ:^(NSString *groupID) {
    // 创建群组成功
    } fail:^(int code, NSString *msg) {
    // 创建群组失败
    }];
    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_;
    };
    
    // 使用高级版 createGroup 创建一个工作群
    V2TIMGroupInfo info;
    info.groupType = "Work";
    info.groupName = "testWork";
    info.introduction = "this is a test Work group";
    
    V2TIMCreateGroupMemberInfoVector memberInfoList;
    V2TIMCreateGroupMemberInfo memberInfo1;
    memberInfo1.userID = "vinson";
    memberInfoList.PushBack(memberInfo1);
    V2TIMCreateGroupMemberInfo memberInfo2;
    memberInfo2.userID = "park";
    memberInfoList.PushBack(memberInfo2);
    
    auto callback = new ValueCallback<V2TIMString>{};
    callback->SetCallback(
    [=](const V2TIMString& string) {
    // 创建成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 创建失败
    delete callback;
    });
    
    V2TIMManager::GetInstance()->GetGroupManager()->CreateGroup(info, memberInfoList, callback);

    加入群组

    不同类型的群组,加群的方法不同:
    类型
    加群方法
    好友工作群(Work)
    必须由其他群成员邀请
    陌生人社交群(Public)
    用户申请,群主或管理员审批
    临时会议群(Meeting)
    用户可随意加入
    社群(Community)
    用户可随意加入
    直播群(AVChatRoom)
    用户可随意加入
    下面将根据加群流程从简单到复杂进行逐一介绍。
    注意
    接收以下群事件需要您按照上文 群事件监听 中所述,提前调用 addGroupListener 添加群事件监听器。

    自由加群

    临时会议群(Meeting)、直播群(AVChatRoom)和社群(Community)主要用于满足成员随意进出的交互场景,例如在线会议,秀场直播等,因此这几种类型群的入群流程最为简单:
    1. 加群者调用 joinGroup (Android / iOS & Mac / Windows) 加入群组。
    2. 加群者加群成功后,全体群成员(包括加群者本人)都会收到 onMemberEnter (Android / iOS & Mac / Windows) 回调。
    注意:
    工作群(Work)默认不支持自由主动加群,您可以通过调用接口 setGroupInfo (Android / iOS & Mac / Windows)修改 V2TIMGroupInfo 的 groupAddOpt 字段来打开自由加群。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    // 加入群组
    V2TIMManager.getInstance().joinGroup("groupA", "it's me!", new V2TIMCallback() {
    @Override
    public void onSuccess() {
    // 加入群组成功
    }
    
    @Override
    public void onError(int code, String desc) {
    // 加入群组失败
    }
    });
    
    // 监听加入群组事件
    V2TIMManager.getInstance().addGroupListener(new V2TIMGroupListener() {
    @Override
    public void onMemberEnter(String groupID, List<V2TIMGroupMemberInfo> memberList) {
    // 有人加入群组
    }
    });
    
    // 加入群组
    [[V2TIMManager sharedInstance] joinGroup:@"groupA" msg:@"it's me!" succ:^{
    // 加入群组成功
    } fail:^(int code, NSString *desc) {
    // 加入群组失败
    }];
    
    // 监听加入群组事件
    [[V2TIMManager sharedInstance] addGroupListener:self];
    - (void)onMemberEnter:(NSString *)groupID memberList:(NSArray<V2TIMGroupMemberInfo *>*)memberList {
    // 有人加入群组
    }
    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_;
    };
    
    auto callback = new Callback{};
    callback->SetCallback(
    [=]() {
    // 加入群组成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 加入群组失败
    delete callback;
    });
    
    V2TIMManager::GetInstance()->JoinGroup("groupA", "it's me!", callback);
    
    // 监听加入群组事件
    class GroupListener final : public V2TIMGroupListener {
    public:
    GroupListener() = default;
    ~GroupListener() override = default;
    
    void OnMemberEnter(const V2TIMString& groupID, const V2TIMGroupMemberInfoVector& memberList) override {
    // 有人加入群组
    }
    // 其他成员 ...
    };
    // 添加群事件监听器,注意在移除监听器之前需要保持 groupListener 的生命期,以免接收不到事件回调
    GroupListener groupListener;
    V2TIMManager::GetInstance()->AddGroupListener(&groupListener);

    邀请加群

    好友工作群(Work),适用于工作交流,在交互设计上限制用户主动加入,只能由现有的群成员邀请才能加群。 加群步骤为:
    1. 现有的群成员调用 inviteUserToGroup (Android / iOS & Mac / Windows) 邀请另一个用户入群。
    2. 全体群成员(包括邀请者自己)会收到 onMemberInvited (Android / iOS & Mac / Windows) 回调。您可以在这个回调中做一些 UI 上的提示。
    注意:
    1. 从增强版 SDK 7.1 版本开始,除工作群(Work)之外的其他群类型默认都不支持邀请加群,您可以通过调用接口 setGroupInfo (Android / iOS & Mac / Windows)修改 V2TIMGroupInfo 的 groupApproveOpt 字段来打开邀请加群。
    2. 直播群、社群和话题默认不允许邀请入群,也不支持修改。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    // 邀请 userA 用户进入群组 groupA 中
    List<String> userIDList = new ArrayList<>();
    userIDList.add("userA");
    V2TIMManager.getGroupManager().inviteUserToGroup("groupA", userIDList, new V2TIMValueCallback<List<V2TIMGroupMemberOperationResult>>() {
    @Override
    public void onSuccess(List<V2TIMGroupMemberOperationResult> v2TIMGroupMemberOperationResults) {
    // 邀请进群成功
    }
    
    @Override
    public void onError(int code, String desc) {
    // 邀请进群失败
    }
    });
    
    // 监听群组邀请事件
    V2TIMManager.getInstance().addGroupListener(new V2TIMGroupListener() {
    @Override
    public void onMemberInvited(String groupID, V2TIMGroupMemberInfo opUser, List<V2TIMGroupMemberInfo> memberList) {
    // 邀请进群事件。可以在这个回调中做一些 UI 上的提示
    }
    });
    // 邀请 userA 用户进入群组 groupA 中
    [[V2TIMManager sharedInstance] inviteUserToGroup:@"groupA" userList:@[@"userA"] succ:^(NSArray<V2TIMGroupMemberOperationResult *> *resultList) {
    // 邀请进群成功
    } fail:^(int code, NSString *desc) {
    // 邀请进群失败
    }];
    
    // 监听群组邀请事件
    [[V2TIMManager sharedInstance] addGroupListener:self];
    - (void)onMemberInvited:(NSString *)groupID opUser:(V2TIMGroupMemberInfo *)opUser memberList:(NSArray<V2TIMGroupMemberInfo *>*)memberList {
    // 可以在这个回调中做一些 UI 上的提示
    }
    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_;
    };
    
    // 邀请 userA 用户进入群组 groupA 中
    V2TIMStringVector userList;
    userList.PushBack("userA");
    
    auto callback = new ValueCallback<V2TIMGroupMemberOperationResultVector>{};
    callback->SetCallback(
    [=](const V2TIMGroupMemberOperationResultVector& groupMemberOperationResultList) {
    // 邀请进群成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 邀请进群失败
    delete callback;
    });
    
    V2TIMManager::GetInstance()->GetGroupManager()->InviteUserToGroup("groupA", userList, callback);
    
    // 监听群组邀请事件
    class GroupListener final : public V2TIMGroupListener {
    public:
    GroupListener() = default;
    ~GroupListener() override = default;
    
    void OnMemberInvited(const V2TIMString& groupID, const V2TIMGroupMemberInfo& opUser,
    const V2TIMGroupMemberInfoVector& memberList) override {
    // 邀请进群事件。可以在这个回调中做一些 UI 上的提示
    }
    // 其他成员 ...
    };
    // 添加群事件监听器,注意在移除监听器之前需要保持 groupListener 的生命期,以免接收不到事件回调
    GroupListener groupListener;
    V2TIMManager::GetInstance()->AddGroupListener(&groupListener);

    邀请且审批加群

    陌生人社交群(Public)类似 QQ 中的各种兴趣群和部落群,任何人都可以申请入群,但需要经过群主或管理员审批才能真正入群。
    邀请且审批加群的流程如下:
    
    
    流程说明:
    1. 申请者调用 joinGroup (Android / iOS & Mac / Windows) 申请加群。
    2. 群主或管理员收到加群申请通知 onReceiveJoinApplication (Android / iOS & Mac / Windows) ,在其中调用 getGroupApplicationList (Android / iOS & Mac / Windows) 获取加群申请列表。
    3. 群主或管理员遍历加群申请列表,逐一调用 acceptGroupApplication (Android / iOS & Mac / Windows) 同意加群,或调用 refuseGroupApplication (Android / iOS & Mac / Windows) 拒绝加群请求。
    4. 请求加群被同意或者拒绝后,申请者会收到 onApplicationProcessed (Android / iOS & Mac / Windows) 回调。其中 isAgreeJointrue/YES 表示同意加群,反之被拒绝。
    5. 同意加群后,全员(包括请求者)收到 onMemberEnter (Android / iOS & Mac / Windows) 回调,通知群组成员有人进群。
    示例代码如下:
    Android
    iOS & Mac
    Windows
    // ******群主端******//
    // 1、群主端修改加群选项为需要审核
    V2TIMGroupInfo groupInfo = new V2TIMGroupInfo();
    groupInfo.setGroupID("groupB");
    groupInfo.setGroupAddOpt(V2TIMGroupInfo.V2TIM_GROUP_ADD_AUTH);
    V2TIMManager.getGroupManager().setGroupInfo(groupInfo, new V2TIMCallback() {
    @Override
    public void onSuccess() {
    // 修改加群选项成功
    }
    
    @Override
    public void onError(int code, String desc) {
    // 修改加群选项失败
    }
    });
    
    // 2、群主端监听加群请求并处理
    V2TIMManager.getInstance().addGroupListener(new V2TIMGroupListener() {
    @Override
    public void onReceiveJoinApplication(String groupID, V2TIMGroupMemberInfo member, String opReason) {
    V2TIMManager.getGroupManager().getGroupApplicationList(new V2TIMValueCallback<V2TIMGroupApplicationResult>() {
    @Override
    public void onSuccess(V2TIMGroupApplicationResult v2TIMGroupApplicationResult) {
    List<V2TIMGroupApplication> groupApplicationList = v2TIMGroupApplicationResult.getGroupApplicationList();
    for (V2TIMGroupApplication application : groupApplicationList) {
    if (application.getGroupID().equals(groupID) && application.getFromUser().equals(member.getUserID())) {
    // 同意进群
    if (agree) {
    // 同意入群申请
    V2TIMManager.getGroupManager().acceptGroupApplication(application, "agree", new V2TIMCallback() {
    @Override
    public void onSuccess() {
    // 同意入群申请成功
    }
    
    @Override
    public void onError(int code, String desc) {
    // 同意入群申请失败
    }
    });
    } else {
    // 拒绝入群申请
    V2TIMManager.getGroupManager().refuseGroupApplication(application, "not agree", new V2TIMCallback() {
    @Override
    public void onSuccess() {
    // 拒绝入群申请成功
    }
    
    @Override
    public void onError(int code, String desc) {
    // 拒绝入群申请失败
    }
    });
    }
    return;
    }
    }
    
    V2TIMManager.getGroupManager().setGroupApplicationRead(new V2TIMCallback() {
    @Override
    public void onSuccess() {
    // 标记加群申请列表为已读成功
    }
    
    @Override
    public void onError(int code, String desc) {
    // 标记加群申请列表为已读失败
    }
    });
    }
    
    @Override
    public void onError(int code, String desc) {
    // 获取群申请列表失败
    }
    });
    }
    });
    
    // ******用户端******//
    // 1、用户端申请加群
    V2TIMManager.getInstance().joinGroup("groupB", "it's me!", new V2TIMCallback() {
    @Override
    public void onSuccess() {
    // 加入群组成功
    }
    
    @Override
    public void onError(int code, String desc) {
    // 加入群组失败
    }
    });
    // 2、用户端监听加群审批结果
    V2TIMManager.getInstance().addGroupListener(new V2TIMGroupListener() {
    @Override
    public void onApplicationProcessed(String groupID, V2TIMGroupMemberInfo opUser, boolean isAgreeJoin,
    String opReason) {
    // 请求加群申请被处理
    }
    
    @Override
    public void onMemberEnter(String groupID, List<V2TIMGroupMemberInfo> memberList) {
    // 如果加群申请通过,收到该回调
    }
    });
    // ******群主端******//
    // 1、群主端修改加群选项为需要审核
    V2TIMGroupInfo *info = [[V2TIMGroupInfo alloc] init];
    info.groupID = @"groupA";
    info.groupAddOpt = V2TIM_GROUP_ADD_AUTH;
    [[V2TIMManager sharedInstance] setGroupInfo:info succ:^{
    // 修改加群选项成功
    } fail:^(int code, NSString *desc) {
    // 修改加群选项成功
    }];
    
    // 2、群主端监听加群请求并处理
    [[V2TIMManager sharedInstance] addGroupListener:self];
    - (void)onReceiveJoinApplication:(NSString *)groupID member:(V2TIMGroupMemberInfo *)member opReason:(NSString *)opReason {
    [[V2TIMManager sharedInstance] getGroupApplicationList:^(V2TIMGroupApplicationResult *result) {
    for (V2TIMGroupApplication *application in result.applicationList) {
    if ([application.groupID isEqualToString:groupID] && [application.fromUser isEqualToString:member.userID]) {
    // 同意进群
    [[V2TIMManager sharedInstance] acceptGroupApplication:application reason:@"agree" succ:^{
    // 同意入群申请成功
    } fail:^(int code, NSString *desc) {
    // 同意入群申请失败
    }];
    
    // 拒绝进群
    [[V2TIMManager sharedInstance] refuseGroupApplication:application reason:@"refuse" succ:^{
    // 拒绝入群申请成功
    } fail:^(int code, NSString *desc) {
    // 拒绝入群申请失败
    }];
    
    // 标记申请已读
    [[V2TIMManager sharedInstance] setGroupApplicationRead:^{
    // 标记加群申请列表为已读成功
    } fail:^(int code, NSString *desc) {
    // 标记加群申请列表为已读失败
    }];
    }
    }
    } fail:^(int code, NSString *desc) {
    // 获取群申请列表失败
    }];
    }
    
    // ******申请端******//
    // 1、用户端申请加群
    [[V2TIMManager sharedInstance] joinGroup:@"groupA" msg:@"it's me!" succ:^{
    // 加入群组成功
    } fail:^(int code, NSString *desc) {
    // 加入群组失败
    }];
    
    // 2、用户端监听加群审批结果
    [[V2TIMManager sharedInstance] addGroupListener:self];
    - (void)onApplicationProcessed:(NSString *)groupID opUser:(V2TIMGroupMemberInfo *)opUser opResult:(BOOL)isAgreeJoin opReason:(NSString *)opReason {
    // 请求加群申请被处理
    }
    - (void)onMemberEnter:(NSString *)groupID memberList:(NSArray<V2TIMGroupMemberInfo *>*)memberList; {
    // 如果加群申请通过,收到该回调
    }
    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_;
    };
    
    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_;
    };
    
    ////////////////////////////////////////////////// 群主端 //////////////////////////////////////////////////
    
    // 1、群主端修改加群选项为需要审核
    V2TIMGroupInfo info;
    info.groupID = "groupB";
    info.groupAddOpt = V2TIMGroupAddOpt::V2TIM_GROUP_ADD_AUTH;
    info.modifyFlag = V2TIMGroupInfoModifyFlag::V2TIM_GROUP_INFO_MODIFY_FLAG_GROUP_ADD_OPTION;
    auto callback = new Callback;
    callback->SetCallback(
    [=]() {
    // 修改加群选项成功
    delete callback;
    },
    [=](int error_code, const V2TIMString& error_message) {
    // 修改加群选项失败
    delete callback;
    });
    V2TIMManager::GetInstance()->GetGroupManager()->SetGroupInfo(info, callback);
    
    // 2、群主端监听加群请求并处理
    class GroupListener final : public V2TIMGroupListener {
    public:
    GroupListener() = default;
    ~GroupListener() override = default;
    
    void OnReceiveJoinApplication(const V2TIMString& groupID, const V2TIMGroupMemberInfo& member,
    const V2TIMString& opReason) override {
    auto callback = new ValueCallback<V2TIMGroupApplicationResult>{};
    callback->SetCallback(
    [=](const V2TIMGroupApplicationResult& groupApplicationResult) {
    const V2TIMGroupApplicationVector& groupApplicationList =
    groupApplicationResult.applicationList;
    for (size_t i = 0; i < groupApplicationList.Size()