首先去融云开发者注册一波账号,获取AppKey :
然后拉取融云SDK:
platform :ios, '8.0'
inhibit_all_warnings!
target 'your projectName' do
pod 'RongCloudIM/IMKit'
end
然后pod install,会发现SDK已经被你拉取下来了,首先在程序入口AppDelegate.m里初始化融云SDK:
[[RCIM sharedRCIM]initWithAppKey:kRongCloudKey];
[RCIM sharedRCIM].connectionStatusDelegate = self;
[RCIM sharedRCIM].enablePersistentUserInfoCache = YES;
[RCIM sharedRCIM].globalConversationAvatarStyle = RC_USER_AVATAR_CYCLE;
[RCIM sharedRCIM].globalMessageAvatarStyle =RC_USER_AVATAR_CYCLE;
[RCIM sharedRCIM].showUnkownMessageNotificaiton = YES;
[RCIM sharedRCIM].enableMessageAttachUserInfo = YES;
[RCIM sharedRCIM].userInfoDataSource = self;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(connectToRongCloud) name:kLoginSucessNotification object:nil];
// MARK: - RCIMUserInfoDataSource
- (void)getUserInfoWithUserId:(NSString *)userId completion:(void (^)(RCUserInfo *userInfo))completion {
NSLog(@"Rong cloud userID: %@", userId);
if ([userId isEqualToString:kAppUserInfo.userId]) {
RCUserInfo *user = [[RCUserInfo alloc] initWithUserId:userId
name:kAppUserInfo.name
portrait:nil];
//缓存至用户信息
[kRongCloudManager insertWithUser:user];
completion(user);
} else {
__block RCUserInfo *user;
//根据userId去查找相对应的头像和昵称,缓存
[NetTool postWithURLString:[NSString stringWithFormat:@"%@%@",kBaseURL,@"rongCloud/getUserNameAndImage"]
parameters: [UtilityHelper encryptParmar:@{@"uid":userId}]
success:^(NSDictionary *data) {
if ([data[@"reCode"] isEqualToString:@"X0000"]) {
user = [[RCUserInfo alloc] initWithUserId:userId
name:data[@"rel"][@"name"]
portrait:[data[@"rel"][@"image"]length] > 2 ? data[@"rel"][@"image"]: nil];
//缓存至用户信息
[kRongCloudManager insertWithUser:user];
completion(user);
} else {
completion(user);
}
} failure:^(NSError *error) {
completion(user);
}];
}
}
然后在App的登录那里将后台获取到的融云token信息拿过来去连接融云服务器:
// MARK: - 融云服务器连接状态监听
- (void)onRCIMConnectionStatusChanged:(RCConnectionStatus)status {
if (status == ConnectionStatus_Connected) {
NSLog(@"融云服务器连接成功!");
} else {
if (status == ConnectionStatus_SignUp) {
NSLog(@"融云服务器断开连接!");
} else {
NSLog(@"融云服务器连接失败!");
}
}
}
// MARK: - 连接融云服务器
- (void)connectToRongCloud {
[NetTool postWithURLString:[NSString stringWithFormat:@"%@%@",kBaseURL,@"rongCloud/getRongCloudToken"]
parameters:@{@"token":kUserToken}
success:^(NSDictionary *data) {
if ([data[@"reCode"] isEqualToString:@"X0000"]) {
NSString *rongCloudToken = data[@"rel"];
[[NSUserDefaults standardUserDefaults] setObject:rongCloudToken forKey:@"RCToken"];
[[NSUserDefaults standardUserDefaults] synchronize];
[[RCIM sharedRCIM] connectWithToken:rongCloudToken
success:^(NSString *userId) {
//设置当前用户信息
RCUserInfo *currentUserInfo = [[RCUserInfo alloc] initWithUserId:kAppUserInfo.userId
name:kAppUserInfo.name
portrait:kRandomAvatar];
[RCIM sharedRCIM].currentUserInfo = currentUserInfo;
[RCIM sharedRCIM].enablePersistentUserInfoCache = YES;
} error:^(RCConnectErrorCode status) {
} tokenIncorrect:^{
}];
}
} failure:^(NSError *error) {
}];
}
在登录的页面那里发一个通知给App,拿到Token去连接融云的服务器:
[[NSNotificationCenter defaultCenter] postNotificationName:kLoginSucessNotification object:nil];
看融云给出的打印日志会发现,融云的集成是成功了:
接下来就是聊天模块了,仔细看SDK的头文件你会发现,其实融云的程序猿早就写好了这些模块,如果不是高度自定义的话,完全可以new一个VController继承他写好的控制器,其中最核心的两个viewController:RCConversationViewController、RCConversationListViewController,顾明思义,第一个是用来展示聊天会话的,第二个是用来展示绘画列表的。
具体的实现代码如下:
@interface CustomChatListVC () <RCIMReceiveMessageDelegate,UITableViewDataSource,UITableViewDelegate> {
UITableView *_tableView;
NSMutableArray <RCConversation *> * _conversationListArray;
}
@end
@implementation CustomChatListVC
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self refresh];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
_conversationListArray = [NSMutableArray arrayWithArray:[[RCIMClient sharedRCIMClient] getConversationList:@[@(ConversationType_PRIVATE)]]];
[RCIM sharedRCIM].receiveMessageDelegate = self;
_tableView = kTableViewWithConfiguration(self.view, CGRectZero, 0, self, self, nil);
[_tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
}
// MARK: - refreshAction
- (void)refresh {
_conversationListArray = [NSMutableArray arrayWithArray:[[RCIMClient sharedRCIMClient] getConversationList:@[@(ConversationType_PRIVATE)]]];
for (RCConversation *conversation in _conversationListArray) {
__block RCUserInfo *user;
[NetTool postWithURLString:[NSString stringWithFormat:@"%@%@",kBaseURL,@"rongCloud/getUserNameAndImage"]
parameters: [UtilityHelper encryptParmar:@{@"uid":conversation.targetId}]
success:^(NSDictionary *data) {
if ([data[@"reCode"] isEqualToString:@"X0000"]) {
user = [[RCUserInfo alloc] initWithUserId:conversation.targetId
name:data[@"rel"][@"name"]
portrait:[data[@"rel"][@"image"]length] > 2 ? data[@"rel"][@"image"]: nil];
[kRongCloudManager insertWithUser:user];
dispatch_async(dispatch_get_main_queue(), ^{
[_tableView reloadData];
});
}
} failure:^(NSError *error) {
}];
}
}
- (RCUserInfo *)getSenderInfoWithExtra:(NSString *)extraStr targetId:(NSString *)targetId {
NSDictionary *json = [extraStr mj_JSONObject];
return [[RCUserInfo alloc] initWithUserId:targetId name:json[@"name"] portrait:json[@"avatar"]];
}
// MARK: - 接收到消息的回调
- (void)onRCIMReceiveMessage:(RCMessage *)message left:(int)left {
/*NSInteger index = 0;
BOOL exsit = NO;
for (int i = 0 ; i < _conversationListArray.count; i ++) {
RCConversation *conversation = _conversationListArray[i];
if ([conversation.targetId isEqualToString:message.targetId]) {
exsit = YES;
index = i;
break;
}
}
if (exsit) {
//存在
RCConversation *conversation = _conversationListArray[index];
conversation.lastestMessage = message.content;
conversation.unreadMessageCount ++;
[_conversationListArray replaceObjectAtIndex:index withObject:conversation];
dispatch_async(dispatch_get_main_queue(), ^{
[_tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
});
} else {
RCConversation *newConversation = [RCConversation new];
newConversation.lastestMessage = message.content;
newConversation.targetId = message.targetId;
newConversation.senderUserId = message.senderUserId;
newConversation.receivedTime = message.receivedTime;
newConversation.unreadMessageCount ++;
[_conversationListArray addObject:newConversation];
dispatch_async(dispatch_get_main_queue(), ^{
[_tableView reloadData];
});
}*/
[self refresh];
}
// MARK: - UITableVieDataSource &Delegate
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _conversationListArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ChatListCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([ChatListCell class])];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([ChatListCell class]) owner:self options:nil] firstObject];
}
[cell setConversationListModel:_conversationListArray[indexPath.row]];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
RCConversation *model = _conversationListArray[indexPath.row];
model.unreadMessageCount = 0;
[_conversationListArray replaceObjectAtIndex:indexPath.row withObject:model];
CustomChatVC *conversationVC = [[CustomChatVC alloc]initWithConversationType:model.conversationType targetId:model.targetId];
conversationVC.title = [kRongCloudManager getUserWithTargetId:model.targetId].name;
[self.navigationController pushViewController:conversationVC animated:YES];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 80;
}
自定义列表cell:
@implementation ChatListCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
//已读已发送
_tip.clipsToBounds = YES;
_tip.layer.borderWidth = 1.0;
_tip.layer.cornerRadius = 4.0;
//头像
_avatar.clipsToBounds = YES;
_avatar.layer.cornerRadius = _avatar.height / 2.0;
//未读消息
_remindCount.clipsToBounds = YES;
_remindCount.layer.cornerRadius = _remindCount.height / 2.0;
_remindCount.hidden = YES;
}
/*
- (void)setDataWithConversationListModel:(ConversationListModel *)conversationListModel {
RCConversation *model = conversationListModel.conversation;
if (model.unreadMessageCount == 0 ) {
_remindCount.hidden = YES;
} else {
_remindCount.hidden = NO;
_remindCount.text = [NSString stringWithFormat:@"%i",model.unreadMessageCount];
}
if (model.receivedStatus == ReceivedStatus_READ) {
//已读
_tip.layer.borderColor = [UIColor greenColor].CGColor;
_tip.textColor = [UIColor greenColor];
_tip.text = @"已读";
} else {
_tip.layer.borderColor = [UIColor redColor].CGColor;
_tip.textColor = [UIColor redColor];
_tip.text = @"送达";
}
RCUserInfo *sender = [kRongCloudManager getUserWithTargetId:model.targetId];
[_avatar sd_setImageWithURL:[NSURL URLWithString:sender.portraitUri] placeholderImage:[UIImage imageWithColor:[UIColor grayColor] withSize:CGSizeMake(60, 60)]];
//名字
_name.text = sender.name;
//职位名称
_position.text = sender.name;
_message.text = [model.lastestMessage valueForKey:@"_content"];
NSDateFormatter *format = [NSDateFormatter new];
BOOL today = [[NSCalendar currentCalendar] isDateInToday:[NSDate dateWithTimeIntervalSince1970:model.receivedTime/1000]];
if (today) {
[format setDateFormat:@"HH:MM"];
} else {
[format setDateFormat:@"yyyy-MM-dd"];
}
_time.text = [format stringFromDate:[NSDate dateWithTimeIntervalSince1970:model.receivedTime/1000]];
}
*/
// MARK: - private Method
- (void)setConversationListModel:(RCConversation *)model {
if (model.unreadMessageCount == 0 ) {
_remindCount.hidden = YES;
} else {
_remindCount.hidden = NO;
_remindCount.text = [NSString stringWithFormat:@"%i",model.unreadMessageCount];
}
if (model.receivedStatus == ReceivedStatus_READ) {
//已读
_tip.layer.borderColor = [UIColor greenColor].CGColor;
_tip.textColor = [UIColor greenColor];
_tip.text = @"已读";
} else {
_tip.layer.borderColor = [UIColor redColor].CGColor;
_tip.textColor = [UIColor redColor];
_tip.text = @"送达";
}
// RCUserInfo *sender = [self getSenderInfoWithExtra:[model.lastestMessage valueForKey:@"_extra"] targetId:model.targetId];
RCUserInfo *sender = [kRongCloudManager getUserWithTargetId:model.targetId];
//头像
[_avatar sd_setImageWithURL:[NSURL URLWithString:sender.portraitUri] placeholderImage:[UIImage imageWithColor:[UIColor grayColor] withSize:CGSizeMake(60, 60)]];
//名字
_name.text = sender.name;
//职位名称
_position.text = sender.name;
BOOL isMe = [model.lastestMessage.senderUserInfo.userId isEqualToString:kAppUserInfo.userId];
NSString *messageContent = [MessageConvert messageConvertWithMessageContent:model.lastestMessage];
_message.text = isMe?[NSString stringWithFormat:@"我:%@",messageContent]: messageContent;
NSDateFormatter *format = [NSDateFormatter new];
BOOL today = [[NSCalendar currentCalendar] isDateInToday:[NSDate dateWithTimeIntervalSince1970:model.receivedTime/1000]];
if (today) {
[format setDateFormat:@"HH:MM"];
} else {
[format setDateFormat:@"yyyy-MM-dd"];
}
_time.text = [format stringFromDate:[NSDate dateWithTimeIntervalSince1970:model.receivedTime/1000]];
}
- (RCUserInfo *)getSenderInfoWithExtra:(NSString *)extraStr targetId:(NSString *)targetId {
NSDictionary *json = [extraStr mj_JSONObject];
return [[RCUserInfo alloc] initWithUserId:targetId name:json[@"name"] portrait:json[@"avatar"]];
}
MessageConvert.m:
+(NSString *)messageConvertWithMessageContent:(RCMessageContent *)messageContent {
NSString *value = @"";
if ([messageContent isKindOfClass:[RCTextMessage class]]) {
//文本
value = ((RCTextMessage *)messageContent).content;
} else if ([messageContent isKindOfClass:[RCLocationMessage class]]) {
//位置
value = @"[位置]";
} else if ([messageContent isKindOfClass:[RCImageMessage class]]) {
//图片
value = @"[图片]";
} else if ([messageContent isKindOfClass:[RCVoiceMessage class]]) {
//语音
value = @"[语音]";
} else if ([messageContent isKindOfClass:[RCSightMessage class]]) {
//小视频
value = @"[小视频]";
}
return value;
}
由于继承自RCConversationListViewController的ViewController只能在dataSource里面添加custom样式的model,从而达到增加自定义cell的效果:
-(NSMutableArray *)willReloadTableData:(NSMutableArray *)dataSource {
NSArray *customItems = @[@"系统消息1",@"系统消息2"];
for (int i = 0; i<customItems.count; i++) {
RCConversationModel *model = [RCConversationModel new];
model.conversationTitle = customItems[i];
model.conversationModelType = RC_CONVERSATION_MODEL_TYPE_CUSTOMIZATION;
model.isTop = YES;
if (dataSource.count) {
//插入自定义cell
[dataSource insertObject:model atIndex:i];
}
}
return dataSource;
}
- (void)onSelectedTableRow:(RCConversationModelType)conversationModelType
conversationModel:(RCConversationModel *)model
atIndexPath:(NSIndexPath *)indexPath {
if (model.conversationModelType == RC_CONVERSATION_MODEL_TYPE_CUSTOMIZATION) {
//自定义消息cell的点击
} else {
//系统会话列表cell的点击
}
}
- (RCConversationBaseCell *)rcConversationListTableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
SystemChatListCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SystemChatListCell class])];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([SystemChatListCell class]) owner:self options:nil] firstObject];
}
//系统消息cell的配置
return cell;
}
这个刚开始发现的时候,感觉有点坑,他不像环信那样可以直接去重写baseCell里面的东西(只能添加,而不能修改,因为这个VC继承了RCConversationListViewController),各位大兄弟要注意这个地方。
在聊天室要用到自定义的cell,所有我们要重写一个message消息类集成于RCMessageContent,重写一个Cell继承RCMessageCell,具体如下:
#import <RongIMKit/RongIMKit.h>
#import "JobMessage.h"
NS_ASSUME_NONNULL_BEGIN
@interface JobCell : RCMessageCell
@property(nonatomic, strong) UIImageView *bubbleBackgroundView;
-(void)setDataModel:(RCMessageModel *)model;
//+ (CGSize)bubbleSizeWithJobMessageModel:(JobMessage *)model;
@end
NS_ASSUME_NONNULL_END
#import "JobCell.h"
@interface JobCell () {
UILabel *_titles[7];
}
@end
@implementation JobCell
+ (CGSize)sizeForMessageModel:(RCMessageModel *)model
withCollectionViewWidth:(CGFloat)collectionViewWidth
referenceExtraHeight:(CGFloat)extraHeight {
return CGSizeMake(kScreenWidth, 300 + extraHeight);
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self initialize];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self initialize];
}
return self;
}
- (void)initialize {
self.bubbleBackgroundView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
self.bubbleBackgroundView.backgroundColor = [UIColor whiteColor];
self.bubbleBackgroundView.clipsToBounds = YES;
self.bubbleBackgroundView.layer.cornerRadius = 5.0;
[self.messageContentView addSubview:self.bubbleBackgroundView];
for (int i = 0 ; i < 7; i ++) {
_titles[i] = kLabelWithCornerRadius(self.bubbleBackgroundView, CGRectMake(20, i == 0 ? 30 :_titles[i - 1].bottom + 10, 280, 35), [UIColor whiteColor], [UIColor blackColor], 0, kFont(14),@"" , 0.0);
}
self.bubbleBackgroundView.userInteractionEnabled = YES;
UITapGestureRecognizer *longPress =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
[self.bubbleBackgroundView addGestureRecognizer:longPress];
}
- (void)tapAction:(UIGestureRecognizer *)gestureRecognizer {
if ([self.delegate respondsToSelector:@selector(didTapMessageCell:)]) {
[self.delegate didTapMessageCell:self.model];
}
}
- (void)setDataModel:(RCMessageModel *)model {
[super setDataModel:model];
JobMessage *message = (JobMessage *)model.content;
NSDictionary *value = [message.content mj_JSONObject][@"data"];
for (int i = 0; i < 7; i ++) {
_titles[i].text = [NSString stringWithFormat:@"%@:%@\n",[value allKeys][i],[value valueForKey:[value allKeys][i]]];
}
if (message) {
}
//拉伸图片
if (MessageDirection_RECEIVE == self.messageDirection) {
} else {
}
}
+ (CGSize)bubbleSizeWithJobMessageModel:(JobMessage *)message {
return CGSizeMake(300, 300);
}
JobMessage类:
#import <RongIMLib/RongIMLib.h>
#import <RongIMLib/RCMessageContent.h>
NS_ASSUME_NONNULL_BEGIN
@interface JobMessage : RCMessageContent <NSCoding,RCMessageContentView>
@property(nonatomic,strong)NSString *content;
@property(nonatomic, strong) NSString* extra;
+(instancetype)messageWithContent:(NSString *)jsonContent;
@end
NS_ASSUME_NONNULL_END
@implementation JobMessage
+ (instancetype)messageWithContent:(NSString *)jsonContent {
JobMessage *model = [JobMessage new];
if (model) {
model.content = jsonContent;
}
return model;
}
//存储状态和是否计入未读数
+(RCMessagePersistent)persistentFlag {
//存储并计入未读数
return (MessagePersistent_ISCOUNTED);
}
#pragma mark – NSCoding protocol methods
#define KEY_TXTMSG_CONTENT @"content"
#define KEY_TXTMSG_EXTRA @"extra"
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
self.content = [aDecoder decodeObjectForKey:KEY_TXTMSG_CONTENT];
self.extra = [aDecoder decodeObjectForKey:KEY_TXTMSG_EXTRA]; }
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.content forKey:KEY_TXTMSG_CONTENT];
[aCoder encodeObject:self.extra forKey:KEY_TXTMSG_EXTRA];
}
#pragma mark – RCMessageCoding delegate methods
///将消息内容编码成json
-(NSData *)encode {
NSMutableDictionary *dataDict=[NSMutableDictionary dictionary];
[dataDict setObject:self.content forKey:@"content"];
if (self.extra) {
[dataDict setObject:self.extra forKey:@"extra"];
}
NSData *data = [NSJSONSerialization dataWithJSONObject:dataDict
options:kNilOptions
error:nil];
return data;
}
//将json解码生成消息内容
-(void)decodeWithData:(NSData *)data {
__autoreleasing NSError* __error = nil;
if (!data) {
return;
}
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&__error];
NSLog(@"dictionary == %@",dictionary);
if ([dictionary objectForKey:@"content"]) {
self.content = dictionary[@"content"];
NSLog(@"dictionary1111 == %@",dictionary[@"content"]);
self.extra = dictionary[@"extra"];
}else{
NSError *error;
NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:kNilOptions error:nil];
NSString *content ;
if (!data) {
NSLog(@"%@",error);
}else{
content = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
}
self.content = content;
}
}
//您定义的消息类型名,需要在各个平台上保持一致,以保证消息互通,别以 RC 开头,以免和融云系统冲突
+(NSString *)getObjectName {
return @"JobMessageType";
}
//最后一条消息是自定义消息的时候,可以更改在会话列表显示的类型,为了区分消息类型
- (NSString *)conversationDigest {
NSString *contentStr = @"[职位信息]";
return contentStr;
}
@end
然后在ChatVC里注册对应的message消息类和messageCell类:
[self registerClass:[JobCell class] forMessageClass:[JobMessage class]];
在AppDelegate里面注册一波自定义message类型:
[[RCIM sharedRCIM] registerMessageType:[JobMessage class]];
这里特别补充一下关于用户头像和昵称的问题,由于和环信一样,这种IM三方并不负责存储用户或群组信息,这些东西一般是用来存放在自己App的后台服务器上,在加载会话列表的时候需要去后台根据targetId去拉取聊天对话的用户信息,但是有一种更为巧妙的方法就是将发送者的信息(昵称、头像、职位名称等等)存放在消息体中,消息体中有一个字段叫做extra:
{"content":"测试","extra":{
"name":"Chan",
"avatar":"http://xxxx/pic_201808241707108698543.png"}
}
然后根据每条消息的latestMessage.extra字段获取最新一条消息的用户信息,但是注意,这里有一个问题就是加入我一直给一个用户发送消息,但是对方没回复,这时候就不管用了,所以读者也注意到了我上面的代码,用了一个单利对象专门用来缓存对话targeId的RCUserInfo用户信息:
#import "RCUserManager.h"
@implementation RCUserManager
+ (instancetype)shareManager {
static RCUserManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[RCUserManager alloc] init];
});
return manager;
}
- (instancetype)init {
if (self = [super init]) {
_users = [NSMutableArray new];
}
return self;
}
- (void)insertWithUser:(RCUserInfo *)user {
if (_users) {
BOOL exsit = NO;
int index = 0;
for (int i = 0 ; i < _users.count; i ++) {
if ([((RCUserInfo *)_users[i]).userId isEqualToString:user.userId]) {
exsit = YES;
index = i;
break;
}
}
if (exsit) {
[_users replaceObjectAtIndex:index withObject:user];
} else {
[_users addObject:user];
}
}
}
- (RCUserInfo *)getUserWithTargetId:(NSString *)targetId {
RCUserInfo *user;
if (_users.count) {
for (int i = 0 ; i < _users.count; i ++) {
RCUserInfo *user = _users[i];
if ([user.userId isEqualToString:targetId]) {
return user;
break;
}
}
}
return user;
}
由于自己的项目是招聘类App,在和企业沟通的时候,进入聊天室的时候,会出现一条企业发送过来的职位消息,也就是上面自定义的messageCell:
CustomChatVC *conversationVC = [[CustomChatVC alloc]initWithConversationType:ConversationType_PRIVATE targetId:@"1392428"];
JobInfoModel *jobModel = [JobInfoModel mj_objectWithKeyValues:jsonValue[@"data"]];
conversationVC.jobInfoModel = jobModel;
//插入一条对方发送过来的消息
[[RCIMClient sharedRCIMClient] insertIncomingMessage:ConversationType_PRIVATE
targetId:@"1392428"
senderUserId:@"1392428"
receivedStatus:ReceivedStatus_READ
content:[JobMessage messageWithContent:[jsonValue mj_JSONString]]
sentTime:0];
conversationVC.title = @"Chan";
[self.navigationController pushViewController:conversationVC animated:YES];
具体的简单实现就到这里,大致效果如下:
由于聊天室使用的是融云的控制器,也可以进行自定义,但是UI界面方面处理起来比较麻烦,后续再完善一波。