环信头像昵称和昵称怎么在扩展中处理

环信:发送头像和昵称(从消息扩展中获取)
字数1249&阅读2153&&喜欢4
昵称和头像
注意:以下是在官方Demo3.0的基础上修改的。
环信提供了获取头像和昵称的两种方式:
方法一 从APP服务器获取昵称和头像
昵称和头像的获取:当收到一条消息(群消息)时,得到发送者的用户ID,然后查找手机本地数据库是否有此用户ID的昵称和头像,如没有则调用APP服务器接口通过用户ID查询出昵称和头像,然后保存到本地数据库和缓存,下次此用户发来信息即可直接查询缓存或者本地数据库,不需要再次向APP服务器发起请求
昵称和头像的更新:当点击发送者头像时加载用户详情时从APP服务器查询此用户的具体信息然后更新本地数据库和缓存。当用户自己更新昵称或头像时,也可以发送一条透传消息到其他用户和用户所在的群,来更新该用户的昵称和头像。
方法二 从消息扩展中获取昵称和头像
昵称和头像的获取:把用户基本的昵称和头像的URL放到消息的扩展中,通过消息传递给接收方,当收到一条消息时,则能通过消息的扩展得到发送者的昵称和头像URL,然后保存到本地数据库和缓存。当显示昵称和头像时,请从本地或者缓存中读取,不要直接从消息中把赋值拿给界面(否则当用户昵称改变后,同一个人会显示不同的昵称)。
昵称和头像的更新:当扩展消息中的昵称和头像URI与当前本地数据库和缓存中的相应数据不同的时候,需要把新的昵称保存到本地数据库和缓存,并下载新的头像并保存到本地数据库和缓存。
本文主要介绍第二种方法:给消息添加扩展,用于携带昵称和头像信息。先来看下效果:
在消息发送时,设置并发送扩展消息
因为是在官方Demo里修改的,但对其还不熟悉,咋办呢?
其实,环信是基于XMPP优化而来的,而XMPP消息又是基于XML的。已经知道在XMPP里扩展消息的方式了,这里应该也是类似的。只不过首先要找到发送消息的时机。可是我不知道在哪?这里要善用搜索和断点。下面简要的说下我的思路:在项目里搜索【消息】,找到了EaseChatToolbar.h中的-
(void)didSendText:(NSString *)方法(别问我为什么是这个方法,不会告诉你我也是查了很久的)。然后在.m中该方法处设置断点,运行程序,输入文字后点击发送按钮。然后看看程序执行的流程是什么。依次向上修改方法,添加头像和昵称信息。如图:
修改- (BOOL)textView:(UITextView
*)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text中的调用方法。并设定头像和昵称字典,代码如下:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
if ([text isEqualToString:@&\n&]) {
if ([self.delegate respondsToSelector:@selector(didSendText:)]) {
NSDictionary *ext = @{@&accountName&:accountName,@&img&:@&1.z0./animal.png&};
[self.delegate didSendText:textView.text withExt:ext];
self.inputTextView.text = @&&;
[self _willShowInputTextViewToHeight:[self _getTextViewContentH:self.inputTextView]];;
return NO;
return YES;
从新运行程序,发送消息,查看日志。在&body&元素里包含了额外添加的昵称和头像信息。如下:
ChatDemoJCV1[f] SEND: &message type=&chat& to=&easemob-demo#chatdemoui_&
id=&151a0fcc287&&&body&{&ext&:{&img&:&1.z0./animal.png&,&accountName&:&zlanchun&},&to&:&zlanchun1&,&bodies&:[{&type&:&txt&,&msg&:&You&}],&from&:&zlanchun&}&/body&&/message&在聊天框中显示消息里地头像和昵称。因为是测试,所以在ChatViewController.m直接将消息中的昵称和头像赋值给视图(实际应用中不推荐这么做,正如环信方法二缺点所说的,需要自己缓存,从本地提取信息)。
- (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id&IMessageModel&)model
if (model.bodyType == eMessageBodyType_Text
NSString *CellIdentifier = [CustomMessageCell cellIdentifierWithModel:model];
CustomMessageCell *sendCell = (CustomMessageCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (sendCell == nil) {
sendCell = [[CustomMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier model:model];
sendCell.selectionStyle = UITableViewCellSelectionStyleNone;
model.avatarURLPath = model.message.ext[@&img&];
model.nickname = model.message.ext[@&accountName&];
sendCell.model =
return sendC
return nil;
最后,这里只是修改了text类型消息的扩展,还有其他几种类型的消息扩展也可以按照这样来处理。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:2581次
排名:千里之外
原创:19篇
(3)(1)(6)(1)(3)(9)(1)as中的gradle
1![External Libraries下面出现两个v4包,两本v7包,运行时总是报冲突,但是libs下面和gradle里面的v4v7都删除了,还是有两个最后解决的处理方法:
(1)defaultConfig中添加下列
configurations { all*.exclude group: 'com.android.support', module: 'support-v4' }
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1047次
排名:千里之外
原创:11篇
(2)(1)(2)(8)1620人阅读
环信SDK使用(4)
我这边用的是环信demo 2.0 的,3.0的我不太清楚。
注意:我这里所说的是单聊页面上的昵称和头像的显示,而非是群聊。
先找到EMChatViewBaseCell.m。
在该文件中找到setMessageModel方法。如下图所示。
然后在该方法里面进行更改操作的处理。
1、MessageModel里面有一个参数是&isSender,是用来判断是不是当前用户发送的。
2、根据 isSender 进行判断
3、if(messageModel.isSender){
_messageModel.headImageURL = [NSURLURLWithString:你的头像的链接];
_messageModel.headImageURL = [NSURLURLWithString:他人的头像链接];
//placeholderImage 可以自己定义,也可以用环信自己的,如果是环信自己的,那么不用更改placeholderImage
UIImage *placeholderImage = [UIImageimageNamed:@&chatListCellHead&];
[self.headImageViewsd_setImageWithURL:_messageModel.headImageURLplaceholderImage:placeholderImage];
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:29962次
排名:千里之外
原创:42篇
转载:15篇
评论:12条
(4)(2)(7)(5)(2)(2)(6)(9)(22)你的浏览器禁用了JavaScript, 请开启后刷新浏览器获得更好的体验!
来献个丑,关于Demo3.0昵称和头像问题的处理,博主写了一篇详细的文章,希望能帮到大家。
最近公司在开发一款创业项目,可以说是以即时通讯功能为主的,所以用到了第三方的即时通讯SDK----环信。相比于国内的几家即时通讯云服务商,像网易云信、融云什么的,环信应该算比较早的了吧,可以说IM云服务的老大。
我们要做的项目类似于微信,有联系人页面、聊天列表与聊天页面、设置页面,刚刚好包括了环信Demo3.0的全部内容,所以理论上应该把Demo直接嵌入工程。由于这个Demo是实现了一些IM的基本UI,但是因为环信的官方文档和视频比较欠缺,维护起来相当麻烦,所以在开发的过程中有好多次决定弃用这个Demo,自己构建UI。但是又考虑到,Demo的代码可以说相当健壮,各种机制都集成的非常好(比如好友申请和删除的回调处理),最终决定还是硬着头皮上,改Demo的UI部分以供自己使用。
环信的官方文档虽然比较欠缺,但是代码的注释和命名还是很好的,基本上可以一目了然每个变量、每个函数在做什么事情。笔者遇到的最大的问题就是好友头像和用户的显示问题,因为环信的服务器是不存储除了用户名和密码以外的其他任何数据的。解决这个问题的办法,就是将你要保存的其他用户信息保存在应用程序自己的服务器上。先来看一张官方图:
如图所示,你需要构建自己的应用服务器。环信的建议是,包括好友体系都不要用环信来维护,最好是由你APP自己的服务器来维护。但是笔者为了简化开发,并没有这样做,而是使用环信维护的好友体系,把昵称和头像存在自己的服务器上,每次从环信上获得当前用户的好友列表,再根据每个好友的用户名到自己的服务器上去获取。
需要显示昵称和头像的地方有以下几处:联系人列表、聊天页表、聊天页面、联系人和群的详情页面。环信Demo3.0中有一个叫做ContactListViewController的类正是联系人列表页面,笔者决定从这个类入手。这个类是一个常见的带Tableview的Controller,找到它的下拉刷新和tableview的几个代理方法进行尝试,发现无论如何也不能完美的实现想要的效果。于是开始研究Demo是怎样显示昵称和头像的,经研究发现,环信是使用国外的App数据储存商Parse来实现储存,于是找到Demo中存取Parse部分的代码:
在ViewDidLoad中,笔者找到了一个叫做UserProfileManager的类(绿色部分),看了看这个类的h和m文件,发现这个类就是管理存取Parse上数据的类,而且全局是一个单例。笔者认真分析了一下这个类的作用,根据它提供给外部使用的方法的名称,发现他的作用主要有以下三个,且是按照以下顺序的:
1----获取当前用户在Parse服务器上的好友数据(头像、昵称),储存到内存中或者本地沙盒中:loadUserProfileInBackgroundWithBuddy:self.contactsSource saveToLoacal:YES completion:NULL
2----根据好友的用户名(环信储存的用户名),返回内存或本地沙盒中保存的昵称:
- (NSString*)getNickNameWithUsername:(NSString*)
3---根据好友的用户名(环信储存的用户名),返回内存或本地沙盒中保存的头像Url:- (UserProfileEntity*)getUserProfileByUsername:(NSString*)
其中2和3其实可以合成一个,因为头像的url一般都是用一个用户的唯一标识(数据库表中的主键)来命名,而这个唯一标识刚好可以是环信服务器上所储存的用户名字段
举个例子,在ViewDidLoad方法中,先调用方法1,获取到昵称和头像,然后在tableview的cellForRowAtIndexPath,也就是给每个cell赋值的那个方法中,先调用方法2和3,再给cell赋值。
如图所示,(绿色部分),根据model.buddy.username属性,获取到环信服务器所保存的用户名,再调用23方法得到昵称和头像url的拼接。
于是根据这个类,笔者仿照它也写了一个单例,给单例加了一个保存所有好友昵称的NSDictionary属性,这个单例对象在APP全局是唯一的,所以该属性在内存中也是唯一的,每次调用获取它的方法,不用担心是空或者重新生成新对象的问题发生。而且最好将属性设置成nonatomic的,这样可以防止在一次网络请求构建改属性的过程中被访问,导致数据错误。但是笔者还是加上了判断。笔者的这个类叫做NickNameAndHeadImage,也就是上面两幅截图中绿色注释部分紧跟的代码。并且还加入了一些判断,比如,如果昵称为空,则显示环信服务器上保存的用户名。当然,如果你想让更新即时的话,你可以在这个类中实现一些发送和接受透传消息的方法,笔者暂时没有写。
大家可以全局搜索UserProfileManager的使用地方(比如按昵称搜索,首字母排序,详情等),发现基本上就是用到了笔者所提到那三种操作,所以,可以用自己仿制的这个单例类完美的代替UserProfileManager的功能,这样就可以在不修改环信Demo逻辑的前提下,接入自己的APP服务器,这样便保留了环信Demo的所有优良特性。
下面将NickName类的代码列出,供大家参考:#import &Foundation/Foundation.h&
@interface NickNameAndHeadImage : NSObject
+(instancetype) shareI
- (void)loadUserProfileInBackgroundWithBuddy:(NSArray*)buddyL
- (NSString*)getNicknameByUserName:(NSString*)
#import &NickNameAndHeadImage.h&
@interface NickNameAndHeadImage()
@property (strong, nonatomic) NSMutableArray *UserN
@property (strong, nonatomic) NSMutableDictionary *NickN
@property (nonatomic) BOOL DownloadHasD
@property (nonatomic) BOOL LoadFromLocalDickD
@implementation NickNameAndHeadImage
static NickNameAndHeadImage* _instance =
+(instancetype) shareInstance
static dispatch_once_t onceT
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init] ;
- (instancetype)init
self = [super init];
if (self) {
_DownloadHasDone = NO;
_LoadFromLocalDickDone = NO;
_UserNames = [NSMutableArray array];
NSMutableDictionary *dic = [[NSUserDefaults standardUserDefaults] objectForKey:dUserDefaults_Dic_NickName];
if (dic == nil || [dic count] == 0) {
_NickNames = [NSMutableDictionary dictionary];
_LoadFromLocalDickDone = YES;
_LoadFromLocalDickDone = YES;
_NickNames = [NSMutableDictionary dictionaryWithDictionary:dic];
- (void)loadUserProfileInBackgroundWithBuddy:(NSArray*)buddyList
_DownloadHasDone = NO;
[_UserNames removeAllObjects];
[_NickNames removeAllObjects];
if (buddyList == nil || [buddyList count] == 0)
for (EMBuddy *buddy in buddyList)
[_UserNames addObject:buddy.username];
[self loadUserProfileInBackgroundWithUsernames];
- (void)loadUserProfileInBackgroundWithUsernames
_DownloadHasDone = NO;
//首先构造Json数组
NSMutableString *jsonString = [[NSMutableString alloc] initWithString:@&{\&mobilelist\&:[&];
for(NSString *mobile in _UserNames){
//2. 遍历数组,取出键值对并按json格式存放
NSString *
= [NSString stringWithFormat:
@&{\&mobile\&:\&%@\&},&,mobile];
[jsonString appendString:string];
// 3. 获取末尾逗号所在位置
NSUInteger location = [jsonString length]-1;
NSRange range
= NSMakeRange(location, 1);
// 4. 将末尾逗号换成结束的]}
[jsonString replaceCharactersInRange:range withString:@&]}&];
NSLog(@&请求昵称时要发送的jsonString = %@&,jsonString);
NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:dUserDefaults_String_LoginToken];
NSString *url = [NSString stringWithFormat:@&customer/contract?token=%@&,token];
NSDictionary *postdic = [NSDictionary dictionaryWithObjectsAndKeys:jsonString,@&mobilelist&,nil];
[HttpUtil POST_Path:url params:postdic completed:^(id JSON,NSString *str)
_LoadFromLocalDickDone = NO;
NSLog(@&打印JSON数据:%@&,str);//打印Json数据
NSString *state = [[JSON objectForKey:@&json&] objectForKey:@&state&];
if ([state isEqualToString:@&1&]) {//获得昵称成功
//打印信息
NSString *msg = [[JSON objectForKey:@&json&] objectForKey:@&msg&];
NSLog(@&获得昵称成功:msg:%@&,msg);
NSArray *array = [[[JSON objectForKey:@&json&] objectForKey:@&data&] objectForKey:@&list&];
for (NSDictionary *dic in array) {
[_NickNames setObject: [dic objectForKey:@&name&] forKey: [dic objectForKey:@&mobile&]];
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[ud setObject:_NickNames forKey:dUserDefaults_Dic_NickName];
[ud synchronize];
_LoadFromLocalDickDone = YES;
_DownloadHasDone = YES;
else//获得昵称失败
_DownloadHasDone = NO;
//打印信息
NSString *msg = [[JSON objectForKey:@&json&] objectForKey:@&msg&];
NSLog(@&获得昵称失败:msg:%@&,msg);
failed:^(NSError *err){
_DownloadHasDone = NO;
[SVProgressHUD showSuccessWithStatus:@&登录失败&];
NSLog(@&获得昵称失败:%@&,err);
- (NSString*)getNicknameByUserName:(NSString*)username
if(_DownloadHasDone == YES)
NSString *string = [_NickNames objectForKey:username];
if (string == nil || [string length] == 0) {
else if(_LoadFromLocalDickDone == YES)
NSMutableDictionary *dic = [[NSUserDefaults standardUserDefaults] objectForKey:dUserDefaults_Dic_NickName];
NSString *string = [dic objectForKey:username];
if (string == nil || [string length] == 0) {
其中,第一行为没有上传头像而有昵称,第二行为有头像有昵称,第三行为有头像无昵称,则显示用户名。
希望可以和大家多交流,做出更完美的App。
不错,理解的很到位!
demo3.0确实比较方便修改,博主看的很详细,很多细节都有讲到,棒棒哒,赞一个!
loadUserProfileInBackgroundWithUsernames 这个方法里的接口是通过把所有用户名作为参数输入进去一次性获取这些用户的信息,是这个意思吧
是的,不过我们也做了单独的一个用户名获取昵称的方法
就是在群聊的时候,那些人的昵称和头像都一次性存储到本地了吗?然后别人发送消息再取出来?
dUserDefaults_Dic_NickName和dUserDefaults_String_LoginToken这个是是什么
是啊,这个是什么?
是所有好友的昵称存入到字典中去了么
要回复文章请先或
知识价值的认可,源自您的赞赏
扫描二维码,你的支付将由imGeek代收后转给对方
感谢您的赞赏
一个开放、互助、协作、创意的社区
一个开放、互助、协作、创意的社区环信:发送头像和昵称(从消息扩展中获取) - 简书
下载简书移动应用
写了13180字,被86人关注,获得了91个喜欢
环信:发送头像和昵称(从消息扩展中获取)
昵称和头像
注意:以下是在官方Demo3.0的基础上修改的。
环信提供了获取头像和昵称的两种方式:
方法一 从APP服务器获取昵称和头像
昵称和头像的获取:当收到一条消息(群消息)时,得到发送者的用户ID,然后查找手机本地数据库是否有此用户ID的昵称和头像,如没有则调用APP服务器接口通过用户ID查询出昵称和头像,然后保存到本地数据库和缓存,下次此用户发来信息即可直接查询缓存或者本地数据库,不需要再次向APP服务器发起请求
昵称和头像的更新:当点击发送者头像时加载用户详情时从APP服务器查询此用户的具体信息然后更新本地数据库和缓存。当用户自己更新昵称或头像时,也可以发送一条透传消息到其他用户和用户所在的群,来更新该用户的昵称和头像。
方法二 从消息扩展中获取昵称和头像
昵称和头像的获取:把用户基本的昵称和头像的URL放到消息的扩展中,通过消息传递给接收方,当收到一条消息时,则能通过消息的扩展得到发送者的昵称和头像URL,然后保存到本地数据库和缓存。当显示昵称和头像时,请从本地或者缓存中读取,不要直接从消息中把赋值拿给界面(否则当用户昵称改变后,同一个人会显示不同的昵称)。
昵称和头像的更新:当扩展消息中的昵称和头像URI与当前本地数据库和缓存中的相应数据不同的时候,需要把新的昵称保存到本地数据库和缓存,并下载新的头像并保存到本地数据库和缓存。
本文主要介绍第二种方法:给消息添加扩展,用于携带昵称和头像信息。先来看下效果:
在消息发送时,设置并发送扩展消息
因为是在官方Demo里修改的,但对其还不熟悉,咋办呢?其实,环信是基于XMPP优化而来的,而XMPP消息又是基于XML的。已经知道在XMPP里扩展消息的方式了,这里应该也是类似的。只不过首先要找到发送消息的时机。可是我不知道在哪?这里要善用搜索和断点。下面简要的说下我的思路:在项目里搜索【消息】,找到了EaseChatToolbar.h中的- (void)didSendText:(NSString *)方法(别问我为什么是这个方法,不会告诉你我也是查了很久的)。然后在.m中该方法处设置断点,运行程序,输入文字后点击发送按钮。然后看看程序执行的流程是什么。依次向上修改方法,添加头像和昵称信息。如图:
修改- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text中的调用方法。并设定头像和昵称字典,代码如下:- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
if ([text isEqualToString:@"\n"]) {
if ([self.delegate respondsToSelector:@selector(didSendText:)]) {
//注释掉的 -- [self.delegate didSendText:textView.text];
//新增头像和昵称扩展
NSDictionary *ext = @{@"accountName":accountName,@"img":@"1.z0./animal.png"};
[self.delegate didSendText:textView.text withExt:ext];
self.inputTextView.text = @"";
[self _willShowInputTextViewToHeight:[self _getTextViewContentH:self.inputTextView]];;
return NO;
return YES;
从新运行程序,发送消息,查看日志。在&body&元素里包含了额外添加的昵称和头像信息。如下:ChatDemoJCV1[f] SEND: &message type="chat" to="easemob-demo#chatdemoui_" id="151a0fcc287"&
&body&{"ext":{"img":"1.z0./animal.png","accountName":"zlanchun"},"to":"zlanchun1","bodies":[{"type":"txt","msg":"You"}],"from":"zlanchun"}&/body&&/message&
在聊天框中显示消息里地头像和昵称。因为是测试,所以在ChatViewController.m直接将消息中的昵称和头像赋值给视图(实际应用中不推荐这么做,正如环信方法二缺点所说的,需要自己缓存,从本地提取信息)。
- (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id&IMessageModel&)model
if (model.bodyType == eMessageBodyType_Text
NSString *CellIdentifier = [CustomMessageCell cellIdentifierWithModel:model];
//发送cell
CustomMessageCell *sendCell = (CustomMessageCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (sendCell == nil) {
sendCell = [[CustomMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier model:model];
sendCell.selectionStyle = UITableViewCellSelectionStyleN
//设定头像和昵称
model.avatarURLPath = model.message.ext[@"img"];
model.nickname = model.message.ext[@"accountName"];
sendCell.model =
return sendC
最后,这里只是修改了text类型消息的扩展,还有其他几种类型的消息扩展也可以按照这样来处理。
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
只要用心去做!哪怕只是一点,依然很精彩!
· 25人关注
· 24人关注
即时通讯类app
· 5人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:

我要回帖

更多关于 ios 环信头像和昵称 的文章

 

随机推荐