最近项目中要加入即时聊天的模块,通过对一些三方开放平台的了解,最终选择了环信(之前对环信的了解相对比较多)。
大家可以看官方文档(http://docs.easemob.com/im/300iosclientintegration/20iossdkimport)导入环信的SDK,我是使用pod方式对环信的SDK进行集成的。关于SDK的集成和基础功能的使用大家完全可以根据官方文档去操作,我在这里只是说说我遇到的问题以及解决问题的方法。
1.将本App中的用户在环信那边进行注册。
集成环信首先要将本App的已有用户以及新注册的用户在环信那边进行注册,注册是在后台进行的,登录是在客户端进行的。在环信那边进行注册的时候密码只需进行一下加密就行,可用户名却不能是中文因此不能直接使用App的用户去环信那边进行注册。我们的做法是利用用户的用户ID与固定字母的组合进行拼接然后作为用户名去环信那边进行注册。
2.异地登录之后消息无法发送
我们项目之前是没有做单点登录的,可如果集成了环信就要和环信保持一致做成单点登录。如果环信用户在其他地方进行了登录会调用一个回调方法,方法名:
-(void)userAccountDidLoginFromOtherDevice{}
此方法是代理EMClientDelegate中的方法。设置代理的方法:
[[EMClient sharedClient] addDelegate:self delegateQueue:nil];
在调用此方法的时候给用户一个对话框,在用户点击确定的时候进行退出登录的操作(在调用此方法的时候就立即做退出登录的操作是不是更好)。退出登录包括App用户的退出登录以及环信用户的退出登录操作。
3.删除聊天页面底部菜单中不需要的的功能按钮
[self.chatBarMoreView removeItematIndex:4];
4.聊天页面设置聊天双方的头像和昵称
如果不进行设置的话会有一个默认的头像,昵称是在环信那边进行注册的时候使用的用户名。
设置本用户的头像容易些,直接在登录的时候将本用户的头像以及昵称存储下来,然后在设置头像和昵称的时候直接进行赋值。
设置对方的头像和昵称稍微麻烦些。我们的项目进入聊天页面有三种方式:1.点击某个用户的帖子页面的发消息按钮 2.点击本用户的聊天列表中某个对话 3.点击推送消息。
要想设置对方的头像和昵称我们需要在一个用户发送消息的时候将自己的头像和昵称也一起发送出去,在接收到对方的头像和昵称的时候将他们存储起来,然后在需要显示的时候再取出来进行显示。
如何发送头像和昵称呢?
我们需要重写发送文本消息的方法,方法名:
- (void)sendTextMessage:(NSString *)text withExt:(NSDictionary*)ext;
我们将用户的头像和昵称放在扩展字ext中。
具体实现:
- (void)sendTextMessage:(NSString *)text withExt:(NSDictionary*)ext
{
NSMutableDictionary * mutableDic = [NSMutableDictionary dictionary];
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
NSString * uid = [defaults objectForKey:USERID];
NSString * userName = [defaults objectForKey:USERNAME];
NSString * hxUid = [NSString stringWithFormat:@"zyjx%@", uid];
mutableDic[@"nickname"] = userName;
mutableDic[@"avatarURLPath"] = [defaults objectForKey:AVATAR];
mutableDic[@"conversationID"] = hxUid;
[super sendTextMessage:text withExt:mutableDic];
}
我们还需要将用户的ID发送过去作为用户的唯一标识。
在什么时候接收到其他人发来的消息以及如何存储其他人发来的包括头像、昵称、ID的扩展字?
在EMChatManagerDelegate代理方法中有一个收到消息的回调方法,方法名:
- (void)messagesDidReceive:(NSArray *)aMessages { }
具体实现:
- (void)messagesDidReceive:(NSArray *)aMessages {
NSLog(@"收到了环信的消息...");
for (EMMessage *msg in aMessages) {
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:msg.ext forKey:msg.from];
[defaults synchronize];
}
设置聊天双方的头像以及昵称的实现代码:
#pragma mark - EaseMessageViewControllerDataSource
- (id)messageViewController:(EaseMessageViewController *)viewController modelForMessage:(EMMessage *)message{ //用户可以根据自己的用户体系,根据message设置用户昵称和头像
id model = nil;
model = [[EaseMessageModel alloc] initWithMessage:message];
if (model.isSender == YES) { // 发送方头像
model.avatarImage = [UIImage imageNamed:@"touxiang_moren"];//默认头像
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
NSString * userName = [defaults objectForKey:USERNAME];
model.avatarURLPath = [defaults objectForKey:AVATAR];;//头像网络地址
model.nickname = userName;//用户昵称
}else{ // 接收方头像
NSLog(@"===personDic:%@", self.personDic);
model.avatarImage = [UIImage imageNamed:@"touxiang_moren"];//默认头像
NSString * avatarURLPath;
NSString * nickName;
if (self.personDic) {
avatarURLPath = self.personDic[@"avatarURLPath"];//头像网络地址
nickName = self.personDic[@"nickname"];//用户昵称
}else{
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
NSDictionary * dic = [defaults objectForKey:self.conversation.conversationId];
NSLog(@"dic:%@", dic);
avatarURLPath = dic[@"avatarURLPath"];//头像网络地址
nickName = dic[@"nickname"];//用户昵称
}
model.avatarURLPath = avatarURLPath;
model.nickname = nickName;
}
return model;
}
(上面这段代码有点长,选择自己想要的就好)
5.当App处于后台的时候显示收到的推送消息
同样在收到环信消息的回调方法中处理。代码:
- (void)messagesDidReceive:(NSArray *)aMessages {
NSLog(@"收到了环信的消息...");
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
// App在后台
if (state == UIApplicationStateBackground) {
//发送本地推送
if (NSClassFromString(@"UNUserNotificationCenter")) { // ios 10
// 设置触发时间
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.01 repeats:NO];
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.sound = [UNNotificationSound defaultSound];
// 提醒,可以根据需要进行弹出,比如显示消息详情,或者是显示“您有一条新消息”
content.body = @"有人发来新消息";
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:msg.messageId content:content trigger:trigger];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:nil];
}else {
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate date]; //触发通知的时间
notification.alertBody = @"有人发来新消息";
notification.alertAction = @"Open";
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
}
}
}
代码直接拷贝就可以。
6.当退出App(杀死App)后收不到环信的消息推送
这是因为我在代码里使用了生产环境下的推送证书的证书名,而App的当前环境还是开发环境。将App打包之后安装到手机上再将App退出就能收到环信的推送消息了。
暂时想到的在集成环信过程中遇到的问题以及解决方法就这些,如果今后遇到新的问题以及解决方法再补充。
本篇文章到这里就结束了,愿大家加班不多工资多,男同胞都有女朋友,女同胞都有男朋友。😊