iOS融云聊天实现出现的问题以及实现半屏聊天记录(补充解决同安卓聊天出现的头像昵称问题)

近期项目中要接入聊天,相对于直播来说这只是一个小需求,但是中间也有一些坑以及挣扎了好久的半屏聊天的实现。
1.首先先说下实现正常的聊天,讲真,融云的文档写的是真不怎么样,模棱两可,首先看下他的

- (void)getUserInfoWithUserId:(NSString *)userId completion:(void(^)(RCUserInfo* userInfo))completion

方法,按照文档上写的是两个用户,但是写法是一样的,给人一种错觉就是if else 里面只要写一样的就行了,我在后面的操作中也把自己的以及我要聊天的人的信息上传上去了,但是经实践是不对的,而且这个方法是只用实现一次的,也就是在appdelegate里面登录成功后实现一次这个方法就行了,不用每次给谁聊天都掉一下这个方法,正确的写法是if里面给融云上传自己的信息,在else里面请求一下自己服务器userid的数据,这个userid就是你要聊天对象的id再把请求的头像、昵称赋值给

   RCUserInfo *user = [[RCUserInfo alloc]init];
    user.userId = userInfo.member_id;
    user.name = userInfo.basic_info.nickname;
    user.portraitUri = imageUrl;

针对这一块我是写了一个单例,RongYunUserInfo,因为融云的token是有期限的,所以在登录成功之后需要校验rongyun_token是否为空,如果为空,再去服务器请求一下token
2.搞定了头像昵称的显示,列表显示正常了,但是从会话列表跳转到聊天列表,聊天记录不显示了,必须手动刷一次才能正常显示,各种检查代码,都是没问题的,最后没招,只能提工单了,结果答案是在设置所有RCConversationListViewController属性之前必须先设置

chatRoomScene.targetId = model.targetId;
chatRoomScene.conversationType = model.conversationType;

真蛋疼。设置完成之后,好了,聊天的正常事项我们都完成了,下面就是半屏聊天了。
3.实现半屏可能这个方法不是最好的,有更好的方法请告知,先说下我最初的实现方法,也给大家规避一些不好的实现方法,因为,我们是有两个聊天
,外面的完成界面的聊天,里面要实现一个高度只有290的mini聊天界面,但是界面是一样的,


屏幕快照 2016-12-31 下午4.07.48.png

(1)因为最初的聊天、消息是在导航栏上面设置的,正常的VC是不能设置坐标的,后来想到了用特殊的转场动画来实现,因为转场动画是可以设置toVC.view = 290的坐标实现一个mini的VC,这样既保留了导航栏的会话列表还能push到聊天界面,想想都很美好,说干就干了,找了一个简书上一个大神写的VC转场动画,基本都实现了,很开心,但是马丹,我从聊天界面跳转回会话列表的时候,会话列表又变成全屏的了,无论怎么去设置从转场进来的containView的坐标都不行,甚至用了最low的方法,从新拿到做转场动画的主VC的superView来设置也不行,至此,这个方法宣布GG,而且这个方法还有一个致命的问题,当然这个问题不是我们的原因,是融云不支持我们去修改工具栏RCChatSessionInputBarControl的坐标,用转场动画toVC是正常的,从toVC push的聊天界面的样式也是符合要求的minivC,但是他的坐标是按照全屏显示的,虽然导航栏显示的是push过来的,但是RCChatSessionInputBarControl还是在从导航栏开始为起始点屏幕的高度为终止点的位置,聊天的collectionView坐标是可以修改的,但是RCChatSessionInputBarControl不能修改,修改了虽然可以看到,但是不响应点击事件。这样就不能这样做了。
(2)既然要保证RCChatSessionInputBarControl在最下方不能修改,后来想到了用presentViewController来实现,分别present一个回话列表和一个聊天界面,现在有一个问题就是我们需要去更改present出来的VC的透明度,因为present出来vc是吧下面遮盖的,就在网上找到了下设置你要present VC的这三个属性就可以了

 chatRoomScene.definesPresentationContext = YES;
   chatRoomScene.modalPresentationStyle = UIModalPresentationOverCurrentContext;
   chatRoomScene.view.backgroundColor = [UIColor clearColor];

这个地方以及下面的设置都是基于判断是present的是miniVC才这样设置,正常的聊天我们还是按照融云的正常聊天就行了


35CAEE2A-0F8A-446B-8D26-B1C219711B88.png

还是按照上面的方法跳转到聊天界面,因为他是全屏VC我们是可以去修改他的conversationMessageCollectionView的坐标,这样保证了不用修改工具栏的坐标,再自定义一个导航栏就可以了


460544A0-25EF-40BC-B6A2-4A8D3C45313B.png

中间需要去做的就是去监听键盘的弹出以及表情View弹出我们去修改试图的坐标以及自己造的导航栏的坐标动态修改一下试图的坐标就可以了
DFE4BCC8-CA0B-422C-A12D-84639389CE8F.png
1933CB43-A025-453E-B25C-1FC009AB974B.png

因为他的列表还是按照全屏显示的,我们再让列表自动滚动到最下方

 //滚动到最下面
        NSUInteger finalRow = MAX(0, [self.conversationMessageCollectionView numberOfItemsInSection:0] - 1);
        if (0 == finalRow) {
            return;
        }
        NSIndexPath *finalIndexPath = [NSIndexPath indexPathForItem:finalRow inSection:0];
        [self.conversationMessageCollectionView
         scrollToItemAtIndexPath:finalIndexPath
         atScrollPosition:UICollectionViewScrollPositionBottom
         animated:NO];

其中有一个问题就是返回上一级会话列表的时候数据不会和正常的聊天一样进行数据刷新,这也是唯一的不足,我的做法是在聊天界面disappear的时候发一个通知让会话列表去刷新

   [[[[NSNotificationCenter defaultCenter]
      rac_addObserverForName:@"RefreshMessageScene" object:nil]
     takeUntil:[self rac_willDeallocSignal]]
    subscribeNext:^(NSNotification *notification) {
        @strongify(self);
   /*!
      从数据库中重新读取会话列表数据,并刷新会话列表

      @warning 从数据库中重新读取并刷新,会比较耗时,请谨慎使用。
  */
        [self refreshConversationTableViewIfNeeded];
    }];

这个融云官方是不提倡的,但是没别的办法,还望谁看到了有更好办法的给我说一下。
总结,啰里啰嗦说这么多,是希望把自己走的弯路也贴出来给大家一个参考。
更新: 解决同安卓聊天无法正常显示头像昵称的问题
聊天都解决了,但是安卓大兄弟过来说咱们两端聊天的时候,我给你发消息的时候在iOS是正常的,但是你给我发消息的时候在安卓端显示不到你的头像和昵称,其实这个问题很好解决,就是上面提到的我们没法显示头像昵称的问题,因为安卓大兄弟也实现了

- (void)getUserInfoWithUserId:(NSString *)userId completion:(void(^)(RCUserInfo* userInfo))completion

这个方法,但是呢,他里面就是我们之前说的问题请求被聊天人信息时没有实现一次网络请求,所以拿不到我的信息,当时我一直问安卓大兄弟你这个地方请求网络了吗,大兄弟很肯定的告诉我,请求了。直觉告诉我就是这个地方出问题了,我问他呢你是怎么实现的,他说是用携带消息体的方式,安卓大兄弟说他如果用代理自己这边会出问题,那就只好iOS这边改了,这里补充下,融云的消息传递是有两种方式的,一种是实现代理进行网络请求,另一种是携带消息体的方式,就是把用户消息直接包含在消息里面,实现方式,两种方式携带消息体的优先级高,会优先读取消息体,这就是咱们说为啥安卓无法显示iOS信息,因为我用的代理,而安卓用的是携带消息体,我没有携带消息体,他也没有进行网络请求,所以显示就不正常了,携带消息体的写法

    [RCIM sharedRCIM].currentUserInfo.userId = @"使用者ID";
    [RCIM sharedRCIM].currentUserInfo.name = @"名字";
    [RCIM sharedRCIM].currentUserInfo.portraitUri =@"图像";
    //设置发送的消息是否携带用户信息
    [RCIM sharedRCIM].enableMessageAttachUserInfo = YES;

这里面有个坑,因为两种实现方式,我以为实现这种方式之后就不需要再去实现代理了,问工单客服,客服也说不用再实现代理


CA6FF960-27EB-4DD1-A398-ABE3B1DF8D16.png

然后我按照他说的做了,结果就会出现这个叼样子,只会显示User<>

1948835b826b6b7affe0eee50a4fc50e.png

后来再想了下,所有的操作我都没有对用户信息进行保存,这肯定不是正确做法,
然后我又在原来的实现代理的基础上,在前面加上了携带消息体,至此,所有完结,两端显示正常,那么这就有问题了,就按照我之前说的,是两种实现方式,两者都存在很明显是不合理的,然后就又去和安卓大兄弟讨论一番,把我的想法和处理逻辑给他说了下,发现他那边在实现的代理的时候是进行网络请求,但是没有将用户信息请求下来之后再去返回给融云,所以导致了他说的他那边自己显示会有异常,然后改了下就完美解决了,咱的代码再撤销回去。。。。

2018.6.15更新
近期发现,一个用户在没有登录的情况下,收到不同的人给发的聊天消息,或者自己同时给几个人发聊天消息,这时候登录回到聊天界面,会出现几个人使用一个人的聊天头像和昵称,根据数据显示聊天列表的数据源是对的,但是在getuserinfo的代理方法中会出现给的userid和列表数据不一致的情况(比如列表中有9条数据,但是代理方法中只会给6条左右的数据,导致无法比对数据重复的原因,是新包,无缓存情况下)给融云扯皮了两天,最后一点点排查,找到原因是在- (void)getUserInfoWithUserId:(NSString )userId completion:(void(^)(RCUserInfo userInfo))completion中调取自己服务器的userInfo后,在返回completion(userInfo)返回的时候,同时要调用 [[RCIM sharedRCIM] refreshUserInfoCache:user withUserId:x.member_id];刷新缓存的userInfo。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,397评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,652评论 0 15
  • 查大大曾说:女人有三次机会改变命运———上学顶尖,老公一流,三折腾自己,不断受挫并成长!我与多数人一般,属于后者!...
    恒可咿呀阅读 274评论 0 0
  • Class:定义Ivar:定义对象的实例变量,包括类型和名字。Protocol:定义正式协议。objc_prope...
    阿兹尔阅读 138评论 0 0