寫(xiě)在前邊:本文由江南大神的環(huán)信集成demo衍生而來(lái)!
附上大神的集成鏈接:http://www.imgeek.org/article/825307886
通過(guò)官方的文檔我們知道有兩種顯示頭像和昵稱(chēng)的方式(http://docs.easemob.com/im/490integrationcases/10nickname官方文檔)
這里主要講方式二?。ㄍㄟ^(guò)擴(kuò)展消息傳遞顯示)
這里主要有三個(gè)類(lèi)需要改,分別是:
EaseMessageViewController
EaseBaseMessageCell
chatUIhelper
首先我們需要在發(fā)送消息的時(shí)候添加擴(kuò)展字段,在EaseMessageViewController.m里??梢钥吹接幸韵路椒ǎ?/p>
#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];}
有發(fā)送各種消息的,我們要每個(gè)里邊都加擴(kuò)展字段么?那恐怕要累死咯! ?仔細(xì)看會(huì)發(fā)現(xiàn)發(fā)送消息的方法最后都會(huì)走一個(gè)方法:
- (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];? ? ? ? }? ? }];}
好的,就是這里了,添加擴(kuò)展字段,包含用戶(hù)的頭像地址,昵稱(chēng)和環(huán)信ID。 找到保存用戶(hù)信息的類(lèi)UserCacheInfo,找到相應(yīng)的字段,在這個(gè)方法里添加如下代碼:
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;
這樣第一步就完成了!
接下來(lái)我們要在接收消息的方法里保存?zhèn)鬟^(guò)來(lái)的擴(kuò)展消息里的頭像、昵稱(chēng)和環(huán)信ID,這就用到chatUIhelper.m這個(gè)類(lèi),這個(gè)方法里:
- (void)didReceiveMessages:(NSArray *)aMessages{? ? BOOL isRefreshCons = YES;? ? for(EMMessage *message in aMessages){[UserCacheManager saveInfo:message.ext];// 通過(guò)消息的擴(kuò)展屬性傳遞昵稱(chēng)和頭像時(shí),需要調(diào)用這句代碼緩存? ? ? ? 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);? ? ? ? }? ? }}
關(guān)鍵就是這句話(huà):
[UserCacheManager saveInfo:message.ext];// 通過(guò)消息的擴(kuò)展屬性傳遞昵稱(chēng)和頭像時(shí),需要調(diào)用這句代碼緩存?。?!
到這里頭像和昵稱(chēng)的問(wèn)題就基本解決了!
重要的總是留在最后?。?! ?不看后悔哦?。?!
上兩步完成后你會(huì)驚奇的發(fā)現(xiàn)頭像和昵稱(chēng)正常顯示了,然而當(dāng)你換個(gè)頭像測(cè)試的時(shí)候,你會(huì)發(fā)現(xiàn)很不美妙,頭像沒(méi)有更換,這是什么問(wèn)題呢? ? 這就要用到開(kāi)始講到的第一個(gè)類(lèi)EaseBaseMessageCell.m,我們仔細(xì)看代碼會(huì)發(fā)現(xiàn)它是怎么賦值的,如下:
#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;? ? ? ? }? ? }}
看到這里就明白了是頭像緩存了,直接用的是緩存里的頭像,我們需要更新的話(huà)直接設(shè)置一下緩存策略就可以了,代碼修改如下:
把[self.avatarView sd_setImageWithURL:[NSURL URLWithString:model.avatarURLPath] placeholderImage:model.avatarImage];改成[self.avatarView sd_setImageWithURL:[NSURL URLWithString:model.avatarURLPath] placeholderImage:model.avatarImage options:EMSDWebImageRefreshCached];
然后運(yùn)行一下你會(huì)發(fā)現(xiàn)世界如此美好,大功告成!
對(duì)各位小伙伴you有沒(méi)有幫助呢?
如有任何問(wèn)題,請(qǐng)咨詢(xún)【環(huán)信IM互幫互助群】,群號(hào):340452063 (進(jìn)群記得改名片哦!江南大神也在群里?。?/p>
本人群里的名片:上海-iOS-小碼農(nóng) ?。