融云头像修改问题
上篇文章记录了ios的融云集成过程,如果sdk添加没问题,按步骤复制粘贴应该是没问题的,下面介绍下集成过程中遇到的坑,及解决思路,希望给正在跳坑的人有所帮助。
出现场景 :A-B 正在聊天, A用的是头像1,突然A改成了头像2.此时B用户观察到的用户是头像1
需要场景 : A如果修改头像,正在聊天的B,应该是能及时看到A修改的新头像
融云提供思路:
A.
12.png
经测试ios自定义聊天Cell时这个问题通过这种办法无法解决,且会产生新的问题,用户的头像和用户名显示有问题 比如Android发给ios的消息 ,ios显示的是不是UserName,而是<UserID>,
Ps:此刻已通过内容提供者查询了本用户数据)
B. 服务器保存用户的关系列表,当当前用户产生修改头像的动作时,后台通过大量广播通知好友刷新
此方法没有采用,原因如下
a. 我开发的app中没有用户好友概念
b. 推送存在延迟和丢失,需要后台大量改动
太麻烦了,放弃这种办法
C. 使用自定义消息体,即每条消息中携带自定义的用户信息
缺点如下
a. 我开发的app周期太急,Android版本已完成且开始了小范围内的推广测试 ,无法大范围修改
b.自定义消息体修改太麻烦,每条消息携带,也太消耗资源
解决思路:
综合开发周期和项目现有的情况,决定借鉴下第三种方法
不自定义消息体,在A每次产生修改头像的动作时,不修改原有的消息体,通过携带多余信息的方式,通知正在聊天的对象B, B观察到A的通知, 完成缓存,缺点: 如果A修改以后 不再给B发消息,则B无法看到A头像的变化,对于我基本满足项目需求
第一步:
关闭消息携带用户信息
RCIM.shared().enableMessageAttachUserInfo = false
第二步:
判断用户会话列表Cell中用户信息为空的情况
let userModel = RCIM.shared().getUserInfoCache(model.targetId)
// 没有缓存用户信息 去接口查询
if userModel == nil {
delegate?.refreshUserInfo(userId: model.targetId)
}
会话列表控制器中
// 解决融云头像的一种思路 有好办法 可以去掉
extension HomeRongMessageController: HomeRongMessageCellDelegate {
func refreshUserInfo(userId: String) {
//自己服务器查询本用户的信息,再缓存到本地
UserHandler().requestRongUserInfo(userID: userId, success: { userInfo in
RongHelp.shared.refreshUserInfoCache(userInfo: userInfo)
// 通过此方法只刷新本条会话
// self?.conversationListTableView.reloadRows
}) { (_) in
}
}
}
以上操作已经解决了自定义消息中出现的用户信息为空的极个别情况,和Android发送到iOS的消息用户名显示为<userID>的问题
第三步:(最重要的一步)
分析当前需要A-B 正在聊天,A突然去修改了自己的头像,再返回和B继续聊天,此时B看到的A的头像应该修改
好,首先A产生了修改头像的动作,再继续和B聊天,此时A可以在产生修改头像的动作以后,再给B第一次发送消息时携带自己的信息过去,B接受且缓存下,
缺点 不发送B就看不到A的新头像(如果需求满足的可以继续往下看)
var userMap: [String: String]? = nil
// 我是其他页面产生了修改信息的动作
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let bean = UserToken.shared.userBean {
userMap = [
"id" : "\(bean.userBean.id)",
"name": bean.profileBean.nickName,
"avatar" : TSRouter.fileCheckUrl + bean.profileBean.avatar]
}
}
// 重写这个方法 每次第一次进来的时候 将个人信息带给对方
// 注意我只在最常用的消息体RCTextMessage中携带了, 且RCTextMessage中有很多的extra 记住他的位置,
override func sendMessage(_ messageContent: RCMessageContent!, pushContent: String!) {
if let message = messageContent as? RCTextMessage , let map = userMap {
let data : NSData! = try? JSONEncoder().encode(map) as NSData
let string = NSString(data:data as Data,encoding: String.Encoding.utf8.rawValue)
if let newString = string as String? {
message.extra = newString
super.sendMessage(message, pushContent: pushContent)
userMap = nil
return
}
}
super.sendMessage(messageContent, pushContent: pushContent)
}
以上的步骤是在会话详情页产生的
最后一步当然是接收这个消息(这步在RongHelp这个类中,可查看下上篇文章)
/// 消息个数
func onRCIMReceive(_ message: RCMessage!, left: Int32) {
// 这个是用户用户修改首页底部消息数
NotificationCenter.default.post(name: UserNotification.rongImMessageCount.notification, object: self)
if message.conversationType == RCConversationType.ConversationType_PRIVATE {
do{
if let textMessage = message.content as? RCTextMessage, let extra = textMessage.extra {
let json = JSON(parseJSON: extra)
let userInfo = RCUserInfo(userId: json["id"].stringValue, name: json["name"].stringValue, portrait: json["avatar"].stringValue)
refreshUserInfoCache(userInfo: userInfo)
}
}catch{
print("-------rong 解析异常")
}
}
}
此上已经基本解决了iOS 和Android之间的头像修改显示问题
Android思路同上就不贴具体的实现代码了,回头把集成的代码整理下,再单独写篇文章
PS:上面的坑开发过程中不一定都会遇到,Android实现雷同, 如果遇到,希望有所帮助。