如何处理 环信信鸽获取不到tokentoken慢的问题

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

我要回帖

更多关于 token获取用户信息 的文章

 

随机推荐