写在前边:本文由江南大神的环信集成demo衍生而来!
附上大神的集成链接:http://www.imgeek.org/article/825307886
通过官方的文档我们知道有两种显示头像和昵称的方式(http://docs.easemob.com/im/490integrationcases/10nickname官方文档)
这里主要讲方式二!(通过扩展消息传递显示)
这里主要有三个类需要改,分别是:
EaseMessageViewController
EaseBaseMessageCell
chatUIhelper
首先我们需要在发送消息的时候添加扩展字段,在EaseMessageViewController.m里。可以看到有以下方法:
#pragma mark - send message- (void)_refreshAfterSentMessage:(EMMessage*)aMessage{ if ([self.messsagesSource count] &&[EMClient sharedClient].options.sortMessageByServerTime) { NSString *msgId = aMessage.messageId; EMMessage *last = self.messsagesSource.lastObject; if ([last isKindOfClass:[EMMessage class]]) { __block NSUInteger index = NSNotFound; index = NSNotFound;[self.messsagesSource enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(EMMessage *obj, NSUInteger idx, BOOL *stop) { if ([obj isKindOfClass:[EMMessage class]] &&[obj.messageId isEqualToString:msgId]) { index = idx; *stop = YES; } }]; if (index != NSNotFound) {[self.messsagesSource removeObjectAtIndex:index];[self.messsagesSource addObject:aMessage]; //格式化消息 self.messageTimeIntervalTag = -1; NSArray *formattedMessages =[self formatMessages:self.messsagesSource];[self.dataArray removeAllObjects];[self.dataArray addObjectsFromArray:formattedMessages];[self.tableView reloadData];[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[self.dataArray count] - 1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES]; return; } } }[self.tableView reloadData];}- (void)_sendMessage:(EMMessage *)message{ if (self.conversation.type == EMConversationTypeGroupChat){ message.chatType = EMChatTypeGroupChat; } else if (self.conversation.type == EMConversationTypeChatRoom){ message.chatType = EMChatTypeChatRoom; }[self addMessageToDataSource:message progress:nil]; __weak typeof(self) weakself = self;[[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) { if (!aError) {[weakself _refreshAfterSentMessage:aMessage]; } else {[weakself.tableView reloadData]; } }];}- (void)sendTextMessage:(NSString *)text{ NSDictionary *ext = nil; if (self.conversation.type == EMConversationTypeGroupChat) { NSArray *targets =[self _searchAtTargets:text]; if ([targets count]) { __block BOOL atAll = NO;[targets enumerateObjectsUsingBlock:^(NSString *target, NSUInteger idx, BOOL *stop) { if ([target compare:kGroupMessageAtAll options:NSCaseInsensitiveSearch] == NSOrderedSame) { atAll = YES; *stop = YES; } }]; if (atAll) { ext = @{kGroupMessageAtList: kGroupMessageAtAll}; } else { ext = @{kGroupMessageAtList: targets}; } } }[self sendTextMessage:text withExt:ext];}- (void)sendTextMessage:(NSString *)text withExt:(NSDictionary*)ext{ EMMessage *message =[EaseSDKHelper sendTextMessage:text to:self.conversation.conversationId messageType:[self _messageTypeFromConversationType] messageExt:ext];[self _sendMessage:message];}- (void)sendLocationMessageLatitude:(double)latitude longitude:(double)longitude andAddress:(NSString *)address{ EMMessage *message =[EaseSDKHelper sendLocationMessageWithLatitude:latitude longitude:longitude address:address to:self.conversation.conversationId messageType:[self _messageTypeFromConversationType] messageExt:nil];[self _sendMessage:message];}- (void)sendImageMessageWithData:(NSData *)imageData{ id progress = nil; if (_dataSource &&[_dataSource respondsToSelector:@selector(messageViewController:progressDelegateForMessageBodyType:)]) { progress =[_dataSource messageViewController:self progressDelegateForMessageBodyType:EMMessageBodyTypeImage]; } else{ progress = self; } EMMessage *message =[EaseSDKHelper sendImageMessageWithImageData:imageData to:self.conversation.conversationId messageType:[self _messageTypeFromConversationType] messageExt:nil];[self _sendMessage:message];}- (void)sendImageMessage:(UIImage *)image{ id progress = nil; if (_dataSource &&[_dataSource respondsToSelector:@selector(messageViewController:progressDelegateForMessageBodyType:)]) { progress =[_dataSource messageViewController:self progressDelegateForMessageBodyType:EMMessageBodyTypeImage]; } else{ progress = self; } EMMessage *message =[EaseSDKHelper sendImageMessageWithImage:image to:self.conversation.conversationId messageType:[self _messageTypeFromConversationType] messageExt:nil];[self _sendMessage:message];}- (void)sendVoiceMessageWithLocalPath:(NSString *)localPath duration:(NSInteger)duration{ id progress = nil; if (_dataSource &&[_dataSource respondsToSelector:@selector(messageViewController:progressDelegateForMessageBodyType:)]) { progress =[_dataSource messageViewController:self progressDelegateForMessageBodyType:EMMessageBodyTypeVoice]; } else{ progress = self; } EMMessage *message =[EaseSDKHelper sendVoiceMessageWithLocalPath:localPath duration:duration to:self.conversation.conversationId messageType:[self _messageTypeFromConversationType] messageExt:nil];[self _sendMessage:message];}- (void)sendVideoMessageWithURL:(NSURL *)url{ id progress = nil; if (_dataSource &&[_dataSource respondsToSelector:@selector(messageViewController:progressDelegateForMessageBodyType:)]) { progress =[_dataSource messageViewController:self progressDelegateForMessageBodyType:EMMessageBodyTypeVideo]; } else{ progress = self; } EMMessage *message =[EaseSDKHelper sendVideoMessageWithURL:url to:self.conversation.conversationId messageType:[self _messageTypeFromConversationType] messageExt:nil];[self _sendMessage:message];}
有发送各种消息的,我们要每个里边都加扩展字段么?那恐怕要累死咯! 仔细看会发现发送消息的方法最后都会走一个方法:
- (void)_sendMessage:(EMMessage *)message{ if (self.conversation.type == EMConversationTypeGroupChat){ message.chatType = EMChatTypeGroupChat; } else if (self.conversation.type == EMConversationTypeChatRoom){ message.chatType = EMChatTypeChatRoom; }[self addMessageToDataSource:message progress:nil]; __weak typeof(self) weakself = self;[[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) { if (!aError) {[weakself _refreshAfterSentMessage:aMessage]; } else {[weakself.tableView reloadData]; } }];}
好的,就是这里了,添加扩展字段,包含用户的头像地址,昵称和环信ID。 找到保存用户信息的类UserCacheInfo,找到相应的字段,在这个方法里添加如下代码:
NSMutableDictionary *Muext =[NSMutableDictionary dictionaryWithDictionary:message.ext]; UserCacheInfo *info =[UserCacheManager currUser];[Muext setObject:kCurrEaseUserId forKey:kChatUserId];[Muext setObject:info.NickName forKey:kChatUserNick];[Muext setObject:info.AvatarUrl forKey:kChatUserPic]; message.ext = Muext;
这样第一步就完成了!
接下来我们要在接收消息的方法里保存传过来的扩展消息里的头像、昵称和环信ID,这就用到chatUIhelper.m这个类,这个方法里:
- (void)didReceiveMessages:(NSArray *)aMessages{ BOOL isRefreshCons = YES; for(EMMessage *message in aMessages){[UserCacheManager saveInfo:message.ext];// 通过消息的扩展属性传递昵称和头像时,需要调用这句代码缓存 BOOL needShowNotification = (message.chatType != EMChatTypeChat) ?[self _needShowNotification:message.conversationId] : YES; #ifdef REDPACKET_AVALABLE /** * 屏蔽红包被抢消息的提示 */ NSDictionary *dict = message.ext; needShowNotification = (dict &&[dict valueForKey:RedpacketKeyRedpacketTakenMessageSign]) ? NO : needShowNotification;#endif UIApplicationState state =[[UIApplication sharedApplication] applicationState]; if (needShowNotification) {#if !TARGET_IPHONE_SIMULATOR switch (state) { case UIApplicationStateActive:[self playSoundAndVibration]; break; case UIApplicationStateInactive:[self playSoundAndVibration]; break; case UIApplicationStateBackground:[self showNotificationWithMessage:message]; break; default: break; }#endif } if (_chatVC == nil) { _chatVC =[self _getCurrentChatView]; } BOOL isChatting = NO; if (_chatVC) { isChatting =[message.conversationId isEqualToString:_chatVC.conversation.conversationId]; } if (_chatVC == nil || !isChatting || state == UIApplicationStateBackground) {[self _handleReceivedAtMessage:message]; if (self.conversationListVC) {[_conversationListVC refresh]; } if (self.mainVC) { NOTIFY_POST(kSetupUnreadMessageCount); } return; } if (isChatting) { isRefreshCons = NO; } } if (isRefreshCons) { if (self.conversationListVC) {[_conversationListVC refresh]; } if (self.mainVC) { NOTIFY_POST(kSetupUnreadMessageCount); } }}
关键就是这句话:
[UserCacheManager saveInfo:message.ext];// 通过消息的扩展属性传递昵称和头像时,需要调用这句代码缓存!!!
到这里头像和昵称的问题就基本解决了!
重要的总是留在最后!!! 不看后悔哦!!!
上两步完成后你会惊奇的发现头像和昵称正常显示了,然而当你换个头像测试的时候,你会发现很不美妙,头像没有更换,这是什么问题呢? 这就要用到开始讲到的第一个类EaseBaseMessageCell.m,我们仔细看代码会发现它是怎么赋值的,如下:
#pragma mark - setter- (void)setModel:(id)model{[super setModel:model]; if (model.avatarURLPath) {[self.avatarView sd_setImageWithURL:[NSURL URLWithString:model.avatarURLPath] placeholderImage:model.avatarImage]; } else { self.avatarView.image = model.avatarImage; } _nameLabel.text = model.nickname; if (self.model.isSender) { _hasRead.hidden = YES; switch (self.model.messageStatus) { case EMMessageStatusDelivering: { _statusButton.hidden = YES;[_activity setHidden:NO];[_activity startAnimating]; } break; case EMMessageStatusSuccessed: { _statusButton.hidden = YES;[_activity stopAnimating]; if (self.model.isMessageRead) { _hasRead.hidden = NO; } } break; case EMMessageStatusPending: case EMMessageStatusFailed: {[_activity stopAnimating];[_activity setHidden:YES]; _statusButton.hidden = NO; } break; default: break; } }}
看到这里就明白了是头像缓存了,直接用的是缓存里的头像,我们需要更新的话直接设置一下缓存策略就可以了,代码修改如下:
把[self.avatarView sd_setImageWithURL:[NSURL URLWithString:model.avatarURLPath] placeholderImage:model.avatarImage];改成[self.avatarView sd_setImageWithURL:[NSURL URLWithString:model.avatarURLPath] placeholderImage:model.avatarImage options:EMSDWebImageRefreshCached];
然后运行一下你会发现世界如此美好,大功告成!
对各位小伙伴you有没有帮助呢?
如有任何问题,请咨询【环信IM互帮互助群】,群号:340452063 (进群记得改名片哦!江南大神也在群里!)
本人群里的名片:上海-iOS-小码农 。