创建和管理群组

更新时间:2022-02-28

群组是支持多人沟通的即时通讯系统,本文介绍如何使用环信即时通讯 IM SDK 在实时互动 app 中创建和管理群组,并实现群组相关功能。

环信即时通讯 IM iOS SDK 提供 IEMGroupManager 类和 EMGroup 类,用于管理群组,其中包含如下主要方法:

  • createGroupWithSubject 创建群组;
  • destroyGroup 解散群组;
  • joinPublicGroup 加入公开群组;
  • leaveGroup 退出群组;
  • fetchGroupMembers 获取群成员列表;
  • getGroupMemberListFromServerWithId 获取已加入的群组列表;
  • getJoinedGroups 从本地获取群组列表;
  • getPublicGroupsFromServerWithCursor 获取公开群列表;
  • blockGroup 屏蔽群消息;
  • unblockGroup 取消群消息屏蔽;
  • addDelegate 添加群组事件监听;
  • removeDelegate 移除群组事件监听。

开始前,请确保满足以下条件:

  • 完成 SDK 初始化,详见 快速开始
  • 了解环信即时通讯 IM API 的接口调用频率限制,详见 使用限制
  • 了解群组和群成员数量限制,详见 使用限制

新建群组

1、群组分为私有群和公开群。

私有群不可被搜索到,公开群可以通过 ID 搜索到。目前支持四种群样式 (GroupStyle),如下:

  • EMGroupStylePrivateOnlyOwnerInvite——私有群,只有群主和管理员可以邀请人;
  • EMGroupStylePrivateMemberCanInvite——私有群,群成员也能邀请人进群;
  • EMGroupStylePublicJoinNeedApproval——公开群,加入此群除了群主和管理员邀请,只能通过申请加入此群;
  • EMGroupStylePublicOpenJoin ——公开群,任何人都能加入此群。

2、新建群组,并加入用户,群主和用户根据设置不同,会收到不同的群组事件回调。分为需要用户确认和不需要确认两种情况:

第一种:加群需要用户确认的情况。

- 用户会收到群组回调 `EMGroupManagerDelegate#groupInvitationDidReceive`;
- 用户同意加入群组后,群主会收到回调 `EMGroupManagerDelegate#groupInvitationDidAccept` 和 `EMGroupManagerDelegate#userDidJoinGroup`;其他群成员将会接收到群组事件回调 `EMGroupManagerDelegate#userDidJoinGroup`;
- 如果用户拒绝,群主会收到回调 `EMGroupManagerDelegate#groupInvitationDidDecline`。
  

流程如下:

第二种:如果不需要用户确认的情况,SDK 自动同意了入群邀请。

- 用户会收到群组回调 `EMGroupManagerDelegate#didJoinGroup`;
- 群主会收到每个已加入成员对应的群组事件回调 `EMGroupManagerDelegate#groupInvitationDidAccept` 和 `EMGroupManagerDelegate#userDidJoinGroup`;
- 现有群成员会收到群组事件回调 `EMGroupManagerDelegate#userDidJoinGroup`。
  

3、用户加入群组后,将可以收到群消息。

示例代码如下:

EMGroupOptions *options = [[EMGroupOptions alloc] init];
options.maxUsersCount = self.maxMemNum;
options.IsInviteNeedConfirm = YES;
options.style = EMGroupStylePrivateMemberCanInvite;
NSArray *members = @{@"memeber1",@"member2"};
[[EMClient sharedClient].groupManager createGroupWithSubject:@"subject"
                                                                                                                description:@"description"
                                                                                                                     invitees:members
                                                                                                                        message:@"message"
                                                                                                                        setting:options
                                                                                                                            error:nil];

注:如果 options.IsInviteNeedConfirm 设置为 false,即直接加被邀请人进群。在此情况下,被邀请人设置非自动进群是不起作用的。

解散群组

注意

  • 操作只能群主才能进行。
  • 这是一个危险操作,解散群组后,将删除本地数据库及内存中的群相关信息及群会话。

示例代码如下:

//群组解散后,群成员将会收到 `EMGroupManagerDelegate#didLeaveGroup` 回调。
[[EMClient sharedClient].groupManager destroyGroup:@"groupID"];

用户申请入群

  • 用户只能申请加入公开群。
  • 如果公开群类型为 EMGroupStylePublicOpenJoin,用户直接加入群组;其他群成员会收到群组事件回调 EMGroupManagerDelegate#userDidJoinGroup
  • 如果公开群类型为 EMGroupStylePublicJoinNeedApprova,群主和群管理员会收到群组事件回调 EMGroupManagerDelegate#joinGroupRequestDidReceive

接下来可以选择同意或者拒绝入群申请。

第一种情况:群主和群管理员同意入群申请,申请人会收到群组事件回调 EMGroupManagerDelegate#joinGroupRequestDidApprove;其他群成员会收到群组事件回调 EMGroupManagerDelegate#userDidJoinGroup。 第二种情况:群主和群管理员拒绝入群申请,申请人会收到群组事件回调 EMGroupManagerDelegate#joinGroupRequestDidDecline

用户加群步骤如下:

1、从服务器获取公开群列表获取到想要加入的群组 ID。

2、根据群组 ID 申请加入群组。

示例代码如下:

[[EMClient sharedClient].groupManager joinPublicGroup:@"groupID" error:nil];

退出群组

群成员可主动调用此方法退出群组,退出群组后,该成员将不会再收到群消息。其他成员将会收到群组事件回调 EMGroupManagerDelegate#didLeaveGroup

示例代码如下:

[[[EMClient sharedClient].groupManager leaveGroup:@"groupID" error:nil];

获取群组详情

注意:从 3.7.4 版本开始支持 “是否获取群组成员” 参数。

获取单个群组详情有以下两种方法:

  • aGroup.adminList:从内存获取群组详情。返回结果包括:群组 ID、群组名称、群组描述、群组基本属性、群主、群组管理员列表,默认不包含群成员。
  • getGroupSpecificationFromServerWithId:从服务器获取群组详情。返回结果包括:群组 ID、群组名称、群组描述、群组基本属性、群主、群组管理员列表。另外,若设置 fetchMemberstrue,获取群组详情时同时获取群成员,默认获取最大数量为 200。
/*!
 *  获取群组详情。返回结果包括:群组ID、群组名称、群组描述、群组基本属性、群主、群组管理员列表,默认不包含群成员。
 *
 *  @param aGroupId              群组 ID。
 *  @param fetchMembers          是否获取群组成员,默认最多取 200 人数。
 *          - `true`:是;
 *          - `false`:否。
 *  @param aCompletionBlock      完成的回调。
 *
 */
- (void)getGroupSpecificationFromServerWithId:(NSString *)aGroupId
                                   fetchMembers:(BOOL)fetchMembers
                                   completion:(void (^)(EMGroup *aGroup, EMError *aError))aCompletionBlock;
                                   
//调用:                       
[[EMClient sharedClient].groupManager getGroupSpecificationFromServerWithId:self.group.groupId fetchMembers:YES completion:^(EMGroup *aGroup, EMError *aError) {
    if (!aError) {
        // EMGroup 中包含了很多群组属性,比如群组 ID,群组成员,是否屏蔽群组消息(isBlocked 属性)等,具体到 SDK 中EMGroup.h 头文件查看。
        NSLog(@"获取群组详情成功");
    } else {
        NSLog(@"获取群组详情失败的原因 --- %@", aError.errorDescription);
    }                
}];  


//获取群组详情之后,可在内存中获取管理员列表。
NSArray *admins = aGroup.adminList;           

获取群成员列表

从服务器获取群成员列表,具体如下:

  • 可以通过分页获取群成员:
NSMutableArray *memberList = [[NSMutableArray alloc]init];
NSInteger pageSize = 50;
NSString *cursor = nil;
EMCursorResult *result = [[EMCursorResult alloc]init];
do {
  result = [[EMClient sharedClient].groupManager
                            getGroupMemberListFromServerWithId:@"groupID"
                                                                                    cursor:cursor 
                                                                                pageSize:pageSize 
                                                                                     error:nil];
  [memberList addObjectsFromArray:result.list];
  cursor = result.cursor;
} while (result && result.list < pageSize);
  • 当群成员少于 200 人时,可以通过以下方式获取群成员:
// 第二个参数传入 TRUE,默认取 200 人的群成员列表。
EMGroup *group = [[EMClient sharedClient].groupManager
                                getGroupSpecificationFromServerWithId:@"groupID"
                                                                         fetchMembers:YES 
                                                                                                error:nil];
NSArray *memeberList = [group.memberList];

获取群组列表

  • 用户可以从服务器获取自己加入和创建的群组列表:
NSArray *groupList = [[EMClient sharedClient].groupManager
                                     getJoinedGroupsFromServerWithPage:nil 
                                                                                      pageSize:-1 
                                                                                         error:nil];
  • 用户可以从本地加载本地群组列表,为了保证数据的正确性,需要先从服务器获取自己加入和创建的群组列表:
NSArray *groupList = [[EMClient sharedClient].groupManager getJoinedGroups];
  • 用户还可以分页获取公开群列表:
NSMutableArray *memberList = [[NSMutableArray alloc]init];
NSInteger pageSize = 50;
NSString *cursor = nil;
EMCursorResult *result = [[EMCursorResult alloc]init];
do {
  result = [[EMClient sharedClient].groupManager
                         getPublicGroupsFromServerWithCursor:cursor
                                                                                pageSize:50 
                                                                                     error:nil];
  [memberList addObjectsFromArray:result.list];
  cursor = result.cursor;
} while (result && result.list < pageSize);

屏蔽和解除群消息

群成员可以屏蔽群消息和解除群消息屏蔽,屏蔽群消息后,该成员将不会再接收到群消息。群主和群管理员不能进行此操作。

屏蔽群消息

/**

 * Block group messages, server will blocks the messages from the group, owner can't block the group's message
 * @param aGroupId   Group ID
 * @param pError     Error
   */
   [[EMClient sharedClient].groupManager blockGroup:@"groupID"error:nil];
   

解除屏蔽群

/**
 * Unblock group messages and you can receive all group messages normally
 * @param aGroupId   Group ID
 * @param pError     Error
   */
   [[EMClient sharedClient].groupManager unblockGroup:@"groupID" error:nil];
   

检查是否屏蔽了群消息

可以通过 EMGroup#isBlocked 检查用户是否屏蔽了该群的群消息。在使用此方法检查时,为了保证结果的准确性,需要先从服务器获取群详情,即调用 EMGroup#getGroupSpecificationFromServerWithId

群组事件监听

IEMGroupManager 中提供了群组事件的监听接口。开发者可以通过设置此监听,获取到群组中的事件,并做出相应的处理。如果不再使用该监听,需要移除,防止出现内存泄漏。

示例代码如下:

//添加,移除代理。

- (void)viewDidLoad
  {
    [super viewDidLoad];
    [[EMClient sharedClient].groupManager addDelegate:self delegateQueue:nil];
  }

- (void)dealloc
  {
    [[EMClient sharedClient].groupManager removeDelegate:self];
  }
  
//相关回调。
//Delegate method will be invoked when receiving a group invitation

- (void)groupInvitationDidReceive:(NSString *)aGroupId inviter:(NSString *)aInviter message:(NSString *)aMessage
  {

}

//Delegate method will be invoked when the group owner receives a group request and group's style is EMGroupStylePublicJoinNeedApproval

- (void)joinGroupRequestDidReceive:(EMGroup *)aGroup user:(NSString *)aUsername reason:(NSString *)aReason
  {

}

//Delegate method will be invoked when the group owner approves a join group request

- (void)joinGroupRequestDidApprove:(EMGroup *)aGroup
  {

}

//Delegate method will be invoked when the group owner declines a join group request

- (void)joinGroupRequestDidDecline:(NSString *)aGroupId reason:(NSString *)aReason
  {

}

//Delegate method will be invoked when the group invitation is accepted

- (void)groupInvitationDidAccept:(EMGroup *)aGroup invitee:(NSString *)aInvitee
  {

}

//Delegate method will be invoked when the group invitation is declined.

- (void)groupInvitationDidDecline:(EMGroup *)aGroup invitee:(NSString *)aInvitee reason:(NSString *)aReason
  {

}

//Delegate method will be invoked after SDK automatically accepted the group invitation

- (void)didJoinGroup:(EMGroup *)aGroup inviter:(NSString *)aInviter message:(NSString *)aMessage
  {

}

//Users are added to the mute list

- (void)groupMuteListDidUpdate:(EMGroup *)aGroup addedMutedMembers:(NSArray *)aMutedMembers muteExpire:(NSInteger)aMuteExpire
  {

}

//Users are removed from the mute list

- (void)groupMuteListDidUpdate:(EMGroup *)aGroup removedMutedMembers:(NSArray *)aMutedMembers
  {

}

//Users are added to the white list

- (void)groupWhiteListDidUpdate:(EMGroup *)aGroup addedWhiteListMembers:(NSArray *)aMembers
  {

}

//Users are removed from the white list

- (void)groupWhiteListDidUpdate:(EMGroup *)aGroup removedWhiteListMembers:(NSArray *)aMembers
  {

}

//Group members are all muted

- (void)groupAllMemberMuteChanged:(EMGroup *)aGroup isAllMemberMuted:(BOOL)aMuted
  {

}

//User is added to the admin list

- (void)groupAdminListDidUpdate:(EMGroup *)aGroup addedAdmin:(NSString *)aAdmin
  {

}

//User is removed to the admin list

- (void)groupAdminListDidUpdate:(EMGroup *)aGroup removedAdmin:(NSString *)aAdmin
  {

}

//Owner is updated

- (void)groupOwnerDidUpdate:(EMGroup *)aGroup newOwner:(NSString *)aNewOwner oldOwner:(NSString *)aOldOwner
  {

}

//Delegate method will be invoked when a user joins a group.

- (void)userDidJoinGroup:(EMGroup *)aGroup user:(NSString *)aUsername
  {

}

//Delegate method will be invoked when a user leaves a group.

- (void)userDidLeaveGroup:(EMGroup *)aGroup user:(NSString *)aUsername
  {

}

//Delegate method will be invoked when a user update the announcement from a group.

- (void)groupAnnouncementDidUpdate:(EMGroup *)aGroup announcement:(NSString *)aAnnouncement
  {

}

//Delegate method will be invoked when a user upload share file to a group.

- (void)groupFileListDidUpdate:(EMGroup *)aGroup addedSharedFile:(EMGroupSharedFile *)aSharedFile
  {

}

//Delegate method will be invoked when a user remove share file from a group.

- (void)groupFileListDidUpdate:(EMGroup *)aGroup removedSharedFile:(NSString *)aFileId
  {

}