第 1 步:引入相关头文件 #import “EMSDK.h”。ios
第 2 步:在工程的 AppDelegate 中的如下方法中,调用 SDK 对应方法。git
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //AppKey:注册的AppKey,详细见下面注释。 //apnsCertName:推送证书名(不须要加后缀),详细见下面注释。 EMOptions *options = [EMOptions optionsWithAppkey:@"douser#istore"]; options.apnsCertName = @"istore_dev"; [[EMClient sharedClient] initializeSDKWithOptions:options]; return YES; } // APP进入后台 - (void)applicationDidEnterBackground:(UIApplication *)application { [[EMClient sharedClient] applicationDidEnterBackground:application]; } // APP将要从后台返回 - (void)applicationWillEnterForeground:(UIApplication *)application { [[EMClient sharedClient] applicationWillEnterForeground:application]; }
调用的 SDK 接口参数解释以下:数据库
环信为 IM 部分提供了 APNS 推送功能,若是您要使用,请跳转到APNS离线推送。服务器
注册模式分两种,开放注册和受权注册。网络
EMError *error = [[EMClient sharedClient] registerWithUsername:@"8001" password:@"111111"]; if (error==nil) { NSLog(@"注册成功"); }
登陆:调用 SDK 的登陆接口进行的操做。app
EMError *error = [[EMClient sharedClient] loginWithUsername:@"8001" password:@"111111"]; if (!error) { NSLog(@"登陆成功"); }
自动登陆:即首次登陆成功后,不须要再次调用登陆方法,在下次 APP 启动时,SDK 会自动为您登陆。而且若是您自动登陆失败,也能够读取到以前的会话信息。异步
SDK 中自动登陆属性默认是关闭的,须要您在登陆成功后设置,以便您在下次 APP 启动时不须要再次调用环信登陆,而且能在没有网的状况下获得会话列表。async
EMError *error = [[EMClient sharedClient] loginWithUsername:@"8001" password:@"111111"]; if (!error) { [[EMClient sharedClient].options setIsAutoLogin:YES]; }
自动登陆在如下几种状况下会被取消:ide
因此,在您调用登陆方法前,应该先判断是否设置了自动登陆,若是设置了,则不须要您再调用。测试
BOOL isAutoLogin = [EMClient sharedClient].options.isAutoLogin; if (!isAutoLogin) { EMError *error = [[EMClient sharedClient] loginWithUsername:@"8001" password:@"111111"]; }
SDK 中,若是发生自动登陆,会有如下回调:
/*!
* 自动登陆返回结果
*
* @param aError 错误信息
*/
- (void)didAutoLoginWithError:(EMError *)aError //添加回调监听代理: [[EMClient sharedClient] addDelegate:self delegateQueue:nil];
当掉线时,iOS SDK 会自动重连,只须要监听重连相关的回调,无需进行任何操做。
/*!
* SDK链接服务器的状态变化时会接收到该回调
*
* 有如下几种状况,会引发该方法的调用:
* 1. 登陆成功后,手机没法上网时,会调用该回调
* 2. 登陆成功后,网络状态变化时,会调用该回调
*
* @param aConnectionState 当前状态
*/
- (void)didConnectionStateChanged:(EMConnectionState)aConnectionState;
退出登陆分两种类型:主动退出登陆和被动退出登陆。
logout:YES:是否解除 device token 的绑定,在被动退出时 SDK 内部处理,不须要调用退出方法。
EMError *error = [[EMClient sharedClient] logout:YES]; if (!error) { NSLog(@"退出成功"); }
使用回调方法监听被动退出登陆。
/*! * 当前登陆帐号在其它设备登陆时会接收到该回调 */ - (void)didLoginFromOtherDevice; /*! * 当前登陆帐号已经被从服务器端删除时会收到该回调 */ - (void)didRemovedFromServer;
消息:IM 交互实体,在 SDK 中对应的类型是 EMMessage。EMMessage 由 EMMessageBody 组成。
EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"要发送的消息"]; NSString *from = [[EMClient sharedClient] currentUsername]; //生成Message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 设置为单聊消息 //message.chatType = EMChatTypeGroupChat;// 设置为群聊消息 //message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息
EMImageMessageBody *body = [[EMImageMessageBody alloc] initWithData:data displayName:@"image.png"]; NSString *from = [[EMClient sharedClient] currentUsername]; //生成Message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 设置为单聊消息 //message.chatType = EMChatTypeGroupChat;// 设置为群聊消息 //message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息
EMLocationMessageBody *body = [[EMLocationMessageBody alloc] initWithLatitude:39 longitude:116 address:@"地址"]; NSString *from = [[EMClient sharedClient] currentUsername]; // 生成message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 设置为单聊消息 //message.chatType = EMChatTypeGroupChat;// 设置为群聊消息 //message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息
EMVoiceMessageBody *body = [[EMVoiceMessageBody alloc] initWithLocalPath:@"audioPath" displayName:@"audio"]; body.duration = duration; NSString *from = [[EMClient sharedClient] currentUsername]; // 生成message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 设置为单聊消息 //message.chatType = EMChatTypeGroupChat;// 设置为群聊消息 //message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息
EMVideoMessageBody *body = [[EMVideoMessageBody alloc] initWithLocalPath:@"videoPath" displayName:@"video.mp4"]; NSString *from = [[EMClient sharedClient] currentUsername]; // 生成message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 设置为单聊消息 //message.chatType = EMChatTypeGroupChat;// 设置为群聊消息 //message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息
EMFileMessageBody *body = [[EMFileMessageBody alloc] initWithLocalPath:@"filePath" displayName:@"file"]; NSString *from = [[EMClient sharedClient] currentUsername]; // 生成message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 设置为单聊消息 //message.chatType = EMChatTypeGroupChat;// 设置为群聊消息 //message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息
SDK 提供的一种特殊类型的消息,即 CMD,不会存 db,也不会走 APNS 推送,相似一种指令型的消息。好比您的服务器要通知客户端作某些操做,您能够服务器和客户端提早约定好某个字段,当客户端收到约定好的字段时,执行某种特殊操做。
EMCmdMessageBody *body = [[EMCmdMessageBody alloc] initWithAction:action]; NSString *from = [[EMClient sharedClient] currentUsername]; // 生成message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.messageType = eMessageTypeChat; // 设置为单聊消息 //message.messageType = eConversationTypeGroupChat;// 设置为群聊消息 //message.messageType = eConversationTypeChatRoom;// 设置为聊天室消息
当 SDK 提供的消息类型不知足需求时,开发者能够经过扩展自 SDK 提供的文本、语音、图片、位置等消息类型,从而生成本身须要的消息类型。
这里是扩展自文本消息,若是这个自定义的消息须要用到语音或者图片等,能够扩展自语音、图片消息,亦或是位置消息。
// 以单聊消息举例
EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"要发送的消息"]; NSString *from = [[EMClient sharedClient] currentUsername]; //生成Message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 设置为单聊消息 //message.chatType = EMChatTypeGroupChat;// 设置为群聊消息 //message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息 message.ext = @{@"key":@"value"}; // 扩展消息部分
EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"要发送的消息"]; NSString *from = [[EMClient sharedClient] currentUsername]; //生成Message EMMessage *message = [[EMMessage alloc] initWithConversationID:@"6001" from:from to:@"6001" body:body ext:messageExt]; message.chatType = EMChatTypeChat;// 设置为单聊消息 //message.chatType = EMChatTypeGroupChat;// 设置为群聊消息 //message.chatType = EMChatTypeChatRoom;// 设置为聊天室消息 [[EMClient sharedClient].chatManager importMessages:@[message]];
/*!
* 更新消息到 DB
*
* @param aMessage 消息
*
* @result 是否成功
*/
- (BOOL)updateMessage:(EMMessage *)aMessage; //调用:[[EMClient sharedClient].chatManager updateMessage:aMessage];
会话:操做聊天消息 EMMessage 的容器,在 SDK 中对应的类型是 EMConversation。
根据 conversationId 建立一个 conversation。
[[EMClient sharedClient].chatManager getConversation:@"8001" type:EMConversationTypeChat createIfNotExist:YES]; //EMConversationTypeChat 单聊会话 //EMConversationTypeGroupChat 群聊会话 //EMConversationTypeChatRoom 聊天室会话
[[EMClient sharedClient].chatManager deleteConversation:@"8001" deleteMessages:YES];
[[EMClient sharedClient].chatManager deleteConversations:@[@"8001",@"8002"] deleteMessages:YES];
SDK中提供了三种获取会会话列表的方法。
EMConversation *conversation = [[EMClient sharedClient].chatManager getConversation:@"8001" type:EMConversationTypeChat createIfNotExist:YES];
NSArray *conversations = [[EMClient sharedClient].chatManager getAllConversations];
NSArray *conversations = [[EMClient sharedClient].chatManager loadAllConversationsFromDB];
[EMConversation unreadMessagesCount];
能够经过关键字、消息类型、开始结束时间检索某个会话中的消息。
/*!
* 从数据库获取指定类型的消息,取到的消息按时间排序,若是参考的时间戳为负数,则从最新消息向前取,若是 aLimit 是负数,则获取全部符合条件的消息
*
* @param aType 消息类型
* @param aTimestamp 参考时间戳
* @param aLimit 获取的条数
* @param aSender 消息发送方,若是为空则忽略
* @param aDirection 消息搜索方向
*
* @result 消息列表<EMMessage>
*/
- (NSArray *)loadMoreMessagesWithType:(EMMessageBodyType)aType before:(long long)aTimestamp limit:(int)aLimit from:(NSString*)aSender direction:(EMMessageSearchDirection)aDirection; /*! * 从数据库获取包含指定内容的消息,取到的消息按时间排序,若是参考的时间戳为负数,则从最新消息向前取,若是 aLimit 是负数,则获取全部符合条件的消息 * * @param aKeywords 搜索关键字,若是为空则忽略 * @param aTimestamp 参考时间戳 * @param aLimit 获取的条数 * @param aSender 消息发送方,若是为空则忽略 * @param aDirection 消息搜索方向 * * @result 消息列表<EMMessage> */ - (NSArray *)loadMoreMessagesContain:(NSString*)aKeywords before:(long long)aTimestamp limit:(int)aLimit from:(NSString*)aSender direction:(EMMessageSearchDirection)aDirection; /*! * 从数据库获取指定时间段内的消息,取到的消息按时间排序,为了防止占用太多内存,用户应当制定加载消息的最大数 * * @param aStartTimestamp 毫秒级开始时间 * @param aEndTimestamp 结束时间 * @param aMaxCount 加载消息最大数 * * @result 消息列表<EMMessage> * */ - (NSArray *)loadMoreMessagesFrom:(long long)aStartTimestamp to:(long long)aEndTimestamp maxCount:(int)aMaxCount;
登陆成功以后才能进行聊天操做。发消息时,单聊和群聊调用的是统一接口,区别只是要设置下 message.chatType。
/*!
@property
@brief 发送消息
@discussion
异步方法
*/
- (void)asyncSendMessage:(EMMessage *)aMessage progress:(void (^)(int progress))aProgress completion:(void (^)(EMMessage *message, EMError *error))aProgressCompletion; //调用:[[EMClient sharedClient].chatManager asyncSendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {}];
注册消息回调
//消息回调:EMChatManagerChatDelegate
//注册消息回调 [[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil]; //移除消息回调 [[EMClient sharedClient].chatManager removeDelegate:self];
在线普通消息会走如下回调:
/*!
@method
@brief 接收到一条及以上非cmd消息
*/
- (void)didReceiveMessages:(NSArray *)aMessages;
透传(cmd)在线消息会走如下回调:
/*!
@method
@brief 接收到一条及以上cmd消息
*/
- (void)didReceiveCmdMessages:(NSArray *)aCmdMessages;
// 收到消息的回调,带有附件类型的消息能够用 SDK 提供的下载附件方法下载(后面会讲到)
- (void)didReceiveMessages:(NSArray *)aMessages { for (EMMessage *message in aMessages) { EMMessageBody *msgBody = message.body; switch (msgBody.type) { case EMMessageBodyTypeText: { // 收到的文字消息 EMTextMessageBody *textBody = (EMTextMessageBody *)msgBody; NSString *txt = textBody.text; NSLog(@"收到的文字是 txt -- %@",txt); } break; case EMMessageBodyTypeImage: { // 获得一个图片消息body EMImageMessageBody *body = ((EMImageMessageBody *)msgBody); NSLog(@"大图remote路径 -- %@" ,body.remotePath); NSLog(@"大图local路径 -- %@" ,body.localPath); // // 须要使用sdk提供的下载方法后才会存在 NSLog(@"大图的secret -- %@" ,body.secretKey); NSLog(@"大图的W -- %f ,大图的H -- %f",body.size.width,body.size.height); NSLog(@"大图的下载状态 -- %lu",body.downloadStatus); // 缩略图sdk会自动下载 NSLog(@"小图remote路径 -- %@" ,body.thumbnailRemotePath); NSLog(@"小图local路径 -- %@" ,body.thumbnailLocalPath); NSLog(@"小图的secret -- %@" ,body.thumbnailSecretKey); NSLog(@"小图的W -- %f ,大图的H -- %f",body.thumbnailSize.width,body.thumbnailSize.height); NSLog(@"小图的下载状态 -- %lu",body.thumbnailDownloadStatus); } break; case EMMessageBodyTypeLocation: { EMLocationMessageBody *body = (EMLocationMessageBody *)msgBody; NSLog(@"纬度-- %f",body.latitude); NSLog(@"经度-- %f",body.longitude); NSLog(@"地址-- %@",body.address); } break; case EMMessageBodyTypeVoice: { // 音频sdk会自动下载 EMVoiceMessageBody *body = (EMVoiceMessageBody *)msgBody; NSLog(@"音频remote路径 -- %@" ,body.remotePath); NSLog(@"音频local路径 -- %@" ,body.localPath); // 须要使用sdk提供的下载方法后才会存在(音频会自动调用) NSLog(@"音频的secret -- %@" ,body.secretKey); NSLog(@"音频文件大小 -- %lld" ,body.fileLength); NSLog(@"音频文件的下载状态 -- %lu" ,body.downloadStatus); NSLog(@"音频的时间长度 -- %lu" ,body.duration); } break; case EMMessageBodyTypeVideo: { EMVideoMessageBody *body = (EMVideoMessageBody *)msgBody; NSLog(@"视频remote路径 -- %@" ,body.remotePath); NSLog(@"视频local路径 -- %@" ,body.localPath); // 须要使用sdk提供的下载方法后才会存在 NSLog(@"视频的secret -- %@" ,body.secretKey); NSLog(@"视频文件大小 -- %lld" ,body.fileLength); NSLog(@"视频文件的下载状态 -- %lu" ,body.downloadStatus); NSLog(@"视频的时间长度 -- %lu" ,body.duration); NSLog(@"视频的W -- %f ,视频的H -- %f", body.thumbnailSize.width, body.thumbnailSize.height); // 缩略图sdk会自动下载 NSLog(@"缩略图的remote路径 -- %@" ,body.thumbnailRemotePath); NSLog(@"缩略图的local路径 -- %@" ,body.thumbnailLocalPath); NSLog(@"缩略图的secret -- %@" ,body.thumbnailSecretKey); NSLog(@"缩略图的下载状态 -- %lu" ,body.thumbnailDownloadStatus); } break; case EMMessageBodyTypeFile: { EMFileMessageBody *body = (EMFileMessageBody *)msgBody; NSLog(@"文件remote路径 -- %@" ,body.remotePath); NSLog(@"文件local路径 -- %@" ,body.localPath); // 须要使用sdk提供的下载方法后才会存在 NSLog(@"文件的secret -- %@" ,body.secretKey); NSLog(@"文件文件大小 -- %lld" ,body.fileLength); NSLog(@"文件文件的下载状态 -- %lu" ,body.downloadStatus); } break; default: break; } } }
- (void)didReceiveCmdMessages:(NSArray *)aCmdMessages{ for (EMMessage *message in aCmdMessages) { EMCmdMessageBody *body = (EMCmdMessageBody *)message.body; NSLog(@"收到的action是 -- %@",body.action); } }
- (void)didReceiveCmdMessages:(NSArray *)aCmdMessages{ for (EMMessage *message in aCmdMessages) { // cmd消息中的扩展属性 NSDictionary *ext = message.ext; NSLog(@"cmd消息中的扩展属性是 -- %@",ext) } } // 收到消息回调 - (void)didReceiveMessages:(NSArray *)aMessages{ for (EMMessage *message in aMessages) { // 消息中的扩展属性 NSDictionary *ext = message.ext; NSLog(@"消息中的扩展属性是 -- %@",ext); } }
SDK 接收到消息后,会默认下载:图片消息的缩略图,语音消息的语音,视频消息的视频第一帧。
请先判断你要下载附件没有下载成功以后,在调用如下下载方法,不然SDK下载方法会再次从服务器上获取附件。
[[EMClient sharedClient].chatManager asyncDownloadMessageThumbnail:message progress:nil completion:^(EMMessage *message, EMError *error) { if (!error) { NSLog(@"下载成功,下载后的message是 -- %@",aMessage); } }];
[[EMClient sharedClient].chatManager asyncDownloadMessageAttachments:message progress:nil completion:^(EMMessage *message, EMError *error) { if (!error) { NSLog(@"下载成功,下载后的message是 -- %@",aMessage); } }];
SDK提供了已送达回执,当对方收到您的消息后,您会收到如下回调。
/*!
@method
@brief 接收到一条及以上已送达回执
*/
- (void)didReceiveHasDeliveredAcks:(NSArray *)aMessages;
已读回执须要开发者主动调用的。当用户读取消息后,由开发者主动调用方法。
// 发送已读回执。在这里写只是为了演示发送,在APP中具体在哪里发送须要开发者本身决定。
[[EMClient sharedClient].chatManager asyncSendReadAckForMessage:message];
/*! * 接收到一条及以上已读回执 * * @param aMessages 消息列表<EMMessage> */ - (void)didReceiveHasReadAcks:(NSArray *)aMessages;
注:环信不是好友也能够聊天,不推荐使用环信的好友机制。若是你有本身的服务器或好友关系,请本身维护好友关系。
获取好友列表,环信提供了两种方法。
EMError *error = nil; NSArray *userlist = [[EMClient sharedClient].contactManager getContactsFromServerWithError:&error]; if (!error) { NSLog(@"获取成功 -- %@",buddyList); }
NSArray *userlist = [[EMClient sharedClient].contactManager getContactsFromDB];
环信 iOS SDK 提供了添加好友的方法。
注:若是您已经发过,而且对方没有处理,您将不能再次发送。
EMError *error = [[EMClient sharedClient].contactManager addContact:@"6001" message:@"我想加您为好友"]; if (!error) { NSLog(@"添加成功"); }
当您收到好友请求,若是您没有处理,请本身保存数据,新协议下不会每次都发送。
//注册好友回调
[[EMClient sharedClient].contactManager addDelegate:self delegateQueue:nil]; //移除好友回调 [[EMClient sharedClient].contactManager removeDelegate:self];
监听回调
/*!
* 用户A发送加用户B为好友的申请,用户B会收到这个回调
*
* @param aUsername 用户名
* @param aMessage 附属信息
*/
- (void)didReceiveFriendInvitationFromUsername:(NSString *)aUsername message:(NSString *)aMessage;
EMError *error = [[EMClient sharedClient].contactManager acceptInvitationForUsername:@"8001"]; if (!error) { NSLog(@"发送赞成成功"); }
EMError *error = [[EMClient sharedClient].contactManager declineInvitationForUsername:@"8001"]; if (!error) { NSLog(@"发送拒绝成功"); }
监听回调
/*!
@method
@brief 用户A发送加用户B为好友的申请,用户B赞成后,用户A会收到这个回调
*/
- (void)didReceiveAgreedFromUsername:(NSString *)aUsername; /*! @method @brief 用户A发送加用户B为好友的申请,用户B拒绝后,用户A会收到这个回调 */ - (void)didReceiveDeclinedFromUsername:(NSString *)aUsername;
// 删除好友
EMError *error = [[EMClient sharedClient].contactManager deleteContact:@"6001"]; if (!error) { NSLog(@"删除成功"); }
环信的黑名单体系是独立的,与好友无任何关系。也就是说,您能够将任何人加入黑名单,不论他是否与您是好友关系。同时,若是您将好友好友加入黑名单,则他仍然是您的好友,只不过同时也在黑名单中。
查询黑名单列表,环信提供了两种方法。
EMError *error = nil; NSArray *blacklist = [[EMClient sharedClient].contactManager getBlackListFromServerWithError:&error]; if (!error) { NSLog(@"获取成功 -- %@",blockedList); }
NSArray *blockList = [[EMClient sharedClient].contactManager getBlackListFromDB];
接口调用
// 将6001加入黑名单
EMError *error = [[EMClient sharedClient].contactManager addUserToBlackList:@"6001" relationshipBoth:YES]; if (!error) { NSLog(@"发送成功"); }
接口调用
// 将6001移除黑名单 EMError *error = [[EMClient sharedClient].contactManager removeUserFromBlackList:@"6001"]; if (!error) { NSLog(@"发送成功"); }
群组分为四种类型。
/*!
@enum
@brief 群组类型
@constant EMGroupStylePrivateOnlyOwnerInvite 私有群组,建立完成后,只容许 Owner 邀请用户加入
@constant EMGroupStylePrivateMemberCanInvite 私有群组,建立完成后,只容许 Owner 和群成员邀请用户加入
@constant EMGroupStylePublicJoinNeedApproval 公开群组,建立完成后,只容许 Owner 邀请用户加入; 非群成员用户需发送入群申请,Owner 赞成后才能入组
@constant EMGroupStylePublicOpenJoin 公开群组,建立完成后,容许非群组成员加入,不须要管理员赞成
@discussion
eGroupStyle+Private:私有群组,只容许群组成员邀请人进入
eGroupStyle+Public: 公有群组,容许非群组成员加入
*/
typedef NS_ENUM(NSInteger, EMGroupStyle){ EMGroupStylePrivateOnlyOwnerInvite = 0, EMGroupStylePrivateMemberCanInvite, EMGroupStylePublicJoinNeedApproval, EMGroupStylePublicOpenJoin, };
目前建立群组支持的配置属性有:
同步方法:
EMError *error = nil; EMGroupOptions *setting = [[EMGroupOptions alloc] init]; setting.maxUsersCount = 500; setting.style = EMGroupStylePublicOpenJoin;// 建立不一样类型的群组,这里须要才传入不一样的类型 EMGroup *group = [[EMClient sharedClient].groupManager createGroupWithSubject:@"群组名称" description:@"群组描述" invitees:@[@"6001",@"6002"] message:@"邀请您加入群组" setting:setting error:&error]; if(!error){ NSLog(@"建立成功 -- %@",group); }
/*!
@method
@brief 获取群组信息
@param aGroupId 群组ID
@param aIncludeMembersList 是否获取成员列表
@param pError 错误信息
@return 群组
@discussion
同步方法,会阻塞当前线程
*/
- (EMGroup *)fetchGroupInfo:(NSString *)aGroupId includeMembersList:(BOOL)aIncludeMembersList error:(EMError **)pError; //调用: //EMError *error = nil; //EMGroup *group = [[EMClient sharedClient].groupManager fetchGroupInfo:@"groupId" includeMembersList:YES error:&error];
群组分4种类型,目前 SDK 不支持自主选择是否进群。咱们将针对每种类型讲解加入群组要进行的操做。
注册群组回调:
//EMChatManagerDelegate
//注册群组回调 [[EMClient sharedClient].groupManager addDelegate:self delegateQueue:nil]; //移除群组回调 [[EMClient sharedClient].groupManager removeDelegate:self];
被添加的人会收到回调:
/*!
@method
@brief 用户B设置了自动赞成,用户A邀请用户B入群,SDK 内部进行赞成操做以后,用户B接收到该回调
*/
- (void)didJoinedGroup:(EMGroup *)aGroup inviter:(NSString *)aInviter message:(NSString *)aMessage;
加人接口以下:
EMError *error = nil; [[EMClient sharedClient].groupManager addOccupants:@[@"user1"] toGroup:@"groupId" welcomeMessage:@"message" error:&error];
// 申请加入须要审核的公开群组
EMError *error = nil; [[EMClient sharedClient].groupManager applyJoinPublicGroup:@"groupId" message:@"" error:nil];
只有 Owner 有权限处理进群申请。
1. 收到进群申请。
/*!
@method
@brief 用户A向群组G发送入群申请,群组G的群主O会接收到该回调
*/
- (void)didReceiveJoinGroupApplication:(EMGroup *)aGroup applicant:(NSString *)aApplicant reason:(NSString *)aReason;
2. 赞成进群申请。
/*!
@method
@brief 赞成加入群组的申请
@param aGroupId 所申请的群组 ID
@param aGroupname 申请的群组名称
@param aUsername 申请人的 username
@discussion
须要 Owner 权限
同步方法,会阻塞当前线程
*/
- (EMError *)acceptJoinApplication:(NSString *)aGroupId groupname:(NSString *)aGroupname applicant:(NSString *)aUsername; //调用: //EMError *error = [[EMClient sharedClient].groupManager acceptJoinApplication:@"groupId" groupname:@"subject" applicant:@"user1"];
3. 拒绝加群申请。
EMError *error = [[EMClient sharedClient].groupManager declineJoinApplication:@"groupId" groupname:@"subject" applicant:@"user1" reason:@"拒绝的缘由"];
EMError *error = nil; [[EMClient sharedClient].groupManager joinPublicGroup:@"1410329312753" error:&error];
群主(Owner)不支持退群操做,只能解散群。
退出群组分为主动退群和被动退群。被动退群即为被 Owner 踢出群组。
EMError *error = nil; [[EMClient sharedClient].groupManager leaveGroup:@"1410329312753" error:&error];
会经过如下回调通知被踢者。
/*!
@method
@brief 接收到离开群组,群组被销毁或者被从群中移除
*/
- (void)didReceiveLeavedGroup:(EMGroup *)aGroup reason:(EMGroupLeaveReason)aReason;
解散群组须要 Owner 权限。
EMError *error = nil; [[EMClient sharedClient].groupManager destroyGroup:@"groupId" error:&error]; if (!error) { NSLog(@"解散成功"); }
只有 Owner 有权限修改。
EMError *error = nil; // 修改群名称 [[EMClient sharedClient].groupManager changeGroupSubject:@"要修改的名称" forGroup:@"1410329312753" error:&error]; if (!error) { NSLog(@"修改为功"); }
不推荐使用 ,只有 Owner 有权限操做。
EMError *error = nil; // 修改群描述 EMGroup* group = [[EMClient sharedClient].groupManager changeDescription:@"修改的群描述" forGroup:@"1410329312753" error:&error]; if (!error) { NSLog(@"修改为功"); }
只有 Owner 权限才能调用。
/*!
@method
@brief 将群成员移出群组
@param aOccupants 要请出群组的人的用户名列表
@param aGroupId 群组ID
@param pError 错误信息
@result 返回群组对象
@discussion
此操做须要 Owner 权限
同步方法,会阻塞当前线程
*/
- (EMGroup *)removeOccupants:(NSArray *)aOccupants fromGroup:(NSString *)aGroupId error:(EMError **)pError; //调用: //EMError *error = nil; //[[EMClient sharedClient].groupManager removeOccupants:@[@"user1"] fromGroup:@"1410329312753" error:&error];
只有 Owner 权限才能调用该接口,而且只有 Owner 权限的才能查看群黑名单。
能够将群成员和非群成员的人加入群黑名单。
/*!
@method
@brief 将某些人加入群组黑名单
@param aOccupants 要加入黑名单的用户名列表
@param aGroupId 群组ID
@param pError 错误信息
@result 返回群组对象
@discussion
此操做须要 Owner 权限。被加入黑名单的人,不会再被容许进入群组。
同步方法,会阻塞当前线程
*/
- (EMGroup *)blockOccupants:(NSArray *)aOccupants fromGroup:(NSString *)aGroupId error:(EMError **)pError; //调用: //EMError *error = nil; //EMGroup *group = [[EMClient sharedClient].groupManager blockOccupants:@[@"user1"] fromGroup:@"1410329312753" error:&error];
只有 Owner 权限才能调用该接口,而且只有 Owner 权限的才能查看群黑名单。
从群黑名单移除出去,该用户已经不在群组里了,须要从新加入群组。
/*!
@method
@brief 将某些人从群组黑名单中解除
@param aOccupants 要从黑名单中移除的用户名列表
@param aGroupId 群组ID
@param pError 错误信息
@result 返回群组对象
@discussion
此操做须要 Owner 权限。从黑名单中移除后再也不是群组成员,须要从新加入。
同步方法,会阻塞当前线程
*/
- (EMGroup *)unblockOccupants:(NSArray *)aOccupants forGroup:(NSString *)aGroupId error:(EMError **)pError; //调用: //EMError *error = nil; //EMGroup *group = [[EMClient sharedClient].groupManager unblockOccupants:@[@"user1"] forGroup:@"1410329312753" error:&error];
不容许 Owner 权限的调用。
/*!
@method
@brief 屏蔽/取消屏蔽群组推送
@param aGroupId 群组ID
@param aIgnore 是否屏蔽
@result 错误信息
@discussion
同步方法,会阻塞当前线程
*/
- (EMError *)ignoreGroupPush:(NSString *)aGroupId ignore:(BOOL)aIgnore; //调用: //EMError *error = [[EMClient sharedClient].groupManager ignoreGroupPush:@"1410329312753" ignore:YES];
查看全部当前登陆帐号所在群组,包括建立的和加入的群组,提供了三种方法。
1.从服务器获取与我相关的群组列表
EMError *error = nil; NSArray *myGroups = [[EMClient sharedClient].groupManager getMyGroupsFromServerWithError:&error]; if (!error) { NSLog(@"获取成功 -- %@",myGroups); }
2. 获取数据库中全部的群组
NSArray *groupList = [[EMClient sharedClient].groupManager loadAllMyGroupsFromDB];
3. 取内存中的值
从内存中获取全部群组。
NSArray *groupList = [[EMClient sharedClient].groupManager getAllGroups];
获取指定范围内的公开群。
EMError *error = nil; EMCursorResult *result = [[EMClient sharedClient].groupManager getPublicGroupsFromServerWithCursor:nil pageSize:50 error:&error]; if (!error) { NSLog(@"获取成功 -- %@",result); }