创建和管理群组
更新时间:2022-02-28
群组是支持多人沟通的即时通讯系统,本文介绍如何使用环信即时通讯 IM SDK 在实时互动 app 中创建和管理群组,并实现群组相关功能。
技术原理
环信即时通讯 IM iOS SDK 提供 IEMGroupManager
类和 EMGroup
类,用于管理群组,其中包含如下主要方法:
createGroupWithSubject
创建群组;destroyGroup
解散群组;joinPublicGroup
加入公开群组;leaveGroup
退出群组;fetchGroupMembers
获取群成员列表;getGroupMemberListFromServerWithId
获取已加入的群组列表;getJoinedGroups
从本地获取群组列表;getPublicGroupsFromServerWithCursor
获取公开群列表;blockGroup
屏蔽群消息;unblockGroup
取消群消息屏蔽;addDelegate
添加群组事件监听;removeDelegate
移除群组事件监听。
前提条件
实现方法
新建群组
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、群组名称、群组描述、群组基本属性、群主、群组管理员列表。另外,若设置fetchMembers
为true
,获取群组详情时同时获取群成员,默认获取最大数量为 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
{
}