iOS融云聊天實(shí)現(xiàn)出現(xiàn)的問(wèn)題以及實(shí)現(xiàn)半屏聊天記錄(補(bǔ)充解決同安卓聊天出現(xiàn)的頭像昵稱問(wèn)題)

近期項(xiàng)目中要接入聊天,相對(duì)于直播來(lái)說(shuō)這只是一個(gè)小需求,但是中間也有一些坑以及掙扎了好久的半屏聊天的實(shí)現(xiàn)。
1.首先先說(shuō)下實(shí)現(xiàn)正常的聊天,講真,融云的文檔寫的是真不怎么樣,模棱兩可,首先看下他的

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

方法,按照文檔上寫的是兩個(gè)用戶,但是寫法是一樣的,給人一種錯(cuò)覺(jué)就是if else 里面只要寫一樣的就行了,我在后面的操作中也把自己的以及我要聊天的人的信息上傳上去了,但是經(jīng)實(shí)踐是不對(duì)的,而且這個(gè)方法是只用實(shí)現(xiàn)一次的,也就是在appdelegate里面登錄成功后實(shí)現(xiàn)一次這個(gè)方法就行了,不用每次給誰(shuí)聊天都掉一下這個(gè)方法,正確的寫法是if里面給融云上傳自己的信息,在else里面請(qǐng)求一下自己服務(wù)器userid的數(shù)據(jù),這個(gè)userid就是你要聊天對(duì)象的id再把請(qǐng)求的頭像、昵稱賦值給

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

針對(duì)這一塊我是寫了一個(gè)單例,RongYunUserInfo,因?yàn)槿谠频膖oken是有期限的,所以在登錄成功之后需要校驗(yàn)rongyun_token是否為空,如果為空,再去服務(wù)器請(qǐng)求一下token
2.搞定了頭像昵稱的顯示,列表顯示正常了,但是從會(huì)話列表跳轉(zhuǎn)到聊天列表,聊天記錄不顯示了,必須手動(dòng)刷一次才能正常顯示,各種檢查代碼,都是沒(méi)問(wèn)題的,最后沒(méi)招,只能提工單了,結(jié)果答案是在設(shè)置所有RCConversationListViewController屬性之前必須先設(shè)置

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

真蛋疼。設(shè)置完成之后,好了,聊天的正常事項(xiàng)我們都完成了,下面就是半屏聊天了。
3.實(shí)現(xiàn)半屏可能這個(gè)方法不是最好的,有更好的方法請(qǐng)告知,先說(shuō)下我最初的實(shí)現(xiàn)方法,也給大家規(guī)避一些不好的實(shí)現(xiàn)方法,因?yàn)?,我們是有兩個(gè)聊天
,外面的完成界面的聊天,里面要實(shí)現(xiàn)一個(gè)高度只有290的mini聊天界面,但是界面是一樣的,


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

(1)因?yàn)樽畛醯牧奶?、消息是在?dǎo)航欄上面設(shè)置的,正常的VC是不能設(shè)置坐標(biāo)的,后來(lái)想到了用特殊的轉(zhuǎn)場(chǎng)動(dòng)畫來(lái)實(shí)現(xiàn),因?yàn)檗D(zhuǎn)場(chǎng)動(dòng)畫是可以設(shè)置toVC.view = 290的坐標(biāo)實(shí)現(xiàn)一個(gè)mini的VC,這樣既保留了導(dǎo)航欄的會(huì)話列表還能push到聊天界面,想想都很美好,說(shuō)干就干了,找了一個(gè)簡(jiǎn)書上一個(gè)大神寫的VC轉(zhuǎn)場(chǎng)動(dòng)畫,基本都實(shí)現(xiàn)了,很開(kāi)心,但是馬丹,我從聊天界面跳轉(zhuǎn)回會(huì)話列表的時(shí)候,會(huì)話列表又變成全屏的了,無(wú)論怎么去設(shè)置從轉(zhuǎn)場(chǎng)進(jìn)來(lái)的containView的坐標(biāo)都不行,甚至用了最low的方法,從新拿到做轉(zhuǎn)場(chǎng)動(dòng)畫的主VC的superView來(lái)設(shè)置也不行,至此,這個(gè)方法宣布GG,而且這個(gè)方法還有一個(gè)致命的問(wèn)題,當(dāng)然這個(gè)問(wèn)題不是我們的原因,是融云不支持我們?nèi)バ薷墓ぞ邫赗CChatSessionInputBarControl的坐標(biāo),用轉(zhuǎn)場(chǎng)動(dòng)畫toVC是正常的,從toVC push的聊天界面的樣式也是符合要求的minivC,但是他的坐標(biāo)是按照全屏顯示的,雖然導(dǎo)航欄顯示的是push過(guò)來(lái)的,但是RCChatSessionInputBarControl還是在從導(dǎo)航欄開(kāi)始為起始點(diǎn)屏幕的高度為終止點(diǎn)的位置,聊天的collectionView坐標(biāo)是可以修改的,但是RCChatSessionInputBarControl不能修改,修改了雖然可以看到,但是不響應(yīng)點(diǎn)擊事件。這樣就不能這樣做了。
(2)既然要保證RCChatSessionInputBarControl在最下方不能修改,后來(lái)想到了用presentViewController來(lái)實(shí)現(xiàn),分別present一個(gè)回話列表和一個(gè)聊天界面,現(xiàn)在有一個(gè)問(wèn)題就是我們需要去更改present出來(lái)的VC的透明度,因?yàn)閜resent出來(lái)vc是吧下面遮蓋的,就在網(wǎng)上找到了下設(shè)置你要present VC的這三個(gè)屬性就可以了

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

這個(gè)地方以及下面的設(shè)置都是基于判斷是present的是miniVC才這樣設(shè)置,正常的聊天我們還是按照融云的正常聊天就行了


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

還是按照上面的方法跳轉(zhuǎn)到聊天界面,因?yàn)樗侨罺C我們是可以去修改他的conversationMessageCollectionView的坐標(biāo),這樣保證了不用修改工具欄的坐標(biāo),再自定義一個(gè)導(dǎo)航欄就可以了


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

中間需要去做的就是去監(jiān)聽(tīng)鍵盤的彈出以及表情View彈出我們?nèi)バ薷脑噲D的坐標(biāo)以及自己造的導(dǎo)航欄的坐標(biāo)動(dòng)態(tài)修改一下試圖的坐標(biāo)就可以了
DFE4BCC8-CA0B-422C-A12D-84639389CE8F.png
1933CB43-A025-453E-B25C-1FC009AB974B.png

因?yàn)樗牧斜磉€是按照全屏顯示的,我們?cè)僮屃斜碜詣?dòng)滾動(dòng)到最下方

 //滾動(dòng)到最下面
        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];

其中有一個(gè)問(wèn)題就是返回上一級(jí)會(huì)話列表的時(shí)候數(shù)據(jù)不會(huì)和正常的聊天一樣進(jìn)行數(shù)據(jù)刷新,這也是唯一的不足,我的做法是在聊天界面disappear的時(shí)候發(fā)一個(gè)通知讓會(huì)話列表去刷新

   [[[[NSNotificationCenter defaultCenter]
      rac_addObserverForName:@"RefreshMessageScene" object:nil]
     takeUntil:[self rac_willDeallocSignal]]
    subscribeNext:^(NSNotification *notification) {
        @strongify(self);
   /*!
      從數(shù)據(jù)庫(kù)中重新讀取會(huì)話列表數(shù)據(jù),并刷新會(huì)話列表

      @warning 從數(shù)據(jù)庫(kù)中重新讀取并刷新,會(huì)比較耗時(shí),請(qǐng)謹(jǐn)慎使用。
  */
        [self refreshConversationTableViewIfNeeded];
    }];

這個(gè)融云官方是不提倡的,但是沒(méi)別的辦法,還望誰(shuí)看到了有更好辦法的給我說(shuō)一下。
總結(jié),啰里啰嗦說(shuō)這么多,是希望把自己走的彎路也貼出來(lái)給大家一個(gè)參考。
更新: 解決同安卓聊天無(wú)法正常顯示頭像昵稱的問(wèn)題
聊天都解決了,但是安卓大兄弟過(guò)來(lái)說(shuō)咱們兩端聊天的時(shí)候,我給你發(fā)消息的時(shí)候在iOS是正常的,但是你給我發(fā)消息的時(shí)候在安卓端顯示不到你的頭像和昵稱,其實(shí)這個(gè)問(wèn)題很好解決,就是上面提到的我們沒(méi)法顯示頭像昵稱的問(wèn)題,因?yàn)榘沧看笮值芤矊?shí)現(xiàn)了

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

這個(gè)方法,但是呢,他里面就是我們之前說(shuō)的問(wèn)題請(qǐng)求被聊天人信息時(shí)沒(méi)有實(shí)現(xiàn)一次網(wǎng)絡(luò)請(qǐng)求,所以拿不到我的信息,當(dāng)時(shí)我一直問(wèn)安卓大兄弟你這個(gè)地方請(qǐng)求網(wǎng)絡(luò)了嗎,大兄弟很肯定的告訴我,請(qǐng)求了。直覺(jué)告訴我就是這個(gè)地方出問(wèn)題了,我問(wèn)他呢你是怎么實(shí)現(xiàn)的,他說(shuō)是用攜帶消息體的方式,安卓大兄弟說(shuō)他如果用代理自己這邊會(huì)出問(wèn)題,那就只好iOS這邊改了,這里補(bǔ)充下,融云的消息傳遞是有兩種方式的,一種是實(shí)現(xiàn)代理進(jìn)行網(wǎng)絡(luò)請(qǐng)求,另一種是攜帶消息體的方式,就是把用戶消息直接包含在消息里面,實(shí)現(xiàn)方式,兩種方式攜帶消息體的優(yōu)先級(jí)高,會(huì)優(yōu)先讀取消息體,這就是咱們說(shuō)為啥安卓無(wú)法顯示iOS信息,因?yàn)槲矣玫拇?,而安卓用的是攜帶消息體,我沒(méi)有攜帶消息體,他也沒(méi)有進(jìn)行網(wǎng)絡(luò)請(qǐng)求,所以顯示就不正常了,攜帶消息體的寫法

    [RCIM sharedRCIM].currentUserInfo.userId = @"使用者ID";
    [RCIM sharedRCIM].currentUserInfo.name = @"名字";
    [RCIM sharedRCIM].currentUserInfo.portraitUri =@"圖像";
    //設(shè)置發(fā)送的消息是否攜帶用戶信息
    [RCIM sharedRCIM].enableMessageAttachUserInfo = YES;

這里面有個(gè)坑,因?yàn)閮煞N實(shí)現(xiàn)方式,我以為實(shí)現(xiàn)這種方式之后就不需要再去實(shí)現(xiàn)代理了,問(wèn)工單客服,客服也說(shuō)不用再實(shí)現(xiàn)代理


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

然后我按照他說(shuō)的做了,結(jié)果就會(huì)出現(xiàn)這個(gè)叼樣子,只會(huì)顯示User<>

1948835b826b6b7affe0eee50a4fc50e.png

后來(lái)再想了下,所有的操作我都沒(méi)有對(duì)用戶信息進(jìn)行保存,這肯定不是正確做法,
然后我又在原來(lái)的實(shí)現(xiàn)代理的基礎(chǔ)上,在前面加上了攜帶消息體,至此,所有完結(jié),兩端顯示正常,那么這就有問(wèn)題了,就按照我之前說(shuō)的,是兩種實(shí)現(xiàn)方式,兩者都存在很明顯是不合理的,然后就又去和安卓大兄弟討論一番,把我的想法和處理邏輯給他說(shuō)了下,發(fā)現(xiàn)他那邊在實(shí)現(xiàn)的代理的時(shí)候是進(jìn)行網(wǎng)絡(luò)請(qǐng)求,但是沒(méi)有將用戶信息請(qǐng)求下來(lái)之后再去返回給融云,所以導(dǎo)致了他說(shuō)的他那邊自己顯示會(huì)有異常,然后改了下就完美解決了,咱的代碼再撤銷回去。。。。

2018.6.15更新
近期發(fā)現(xiàn),一個(gè)用戶在沒(méi)有登錄的情況下,收到不同的人給發(fā)的聊天消息,或者自己同時(shí)給幾個(gè)人發(fā)聊天消息,這時(shí)候登錄回到聊天界面,會(huì)出現(xiàn)幾個(gè)人使用一個(gè)人的聊天頭像和昵稱,根據(jù)數(shù)據(jù)顯示聊天列表的數(shù)據(jù)源是對(duì)的,但是在getuserinfo的代理方法中會(huì)出現(xiàn)給的userid和列表數(shù)據(jù)不一致的情況(比如列表中有9條數(shù)據(jù),但是代理方法中只會(huì)給6條左右的數(shù)據(jù),導(dǎo)致無(wú)法比對(duì)數(shù)據(jù)重復(fù)的原因,是新包,無(wú)緩存情況下)給融云扯皮了兩天,最后一點(diǎn)點(diǎn)排查,找到原因是在- (void)getUserInfoWithUserId:(NSString )userId completion:(void(^)(RCUserInfo userInfo))completion中調(diào)取自己服務(wù)器的userInfo后,在返回completion(userInfo)返回的時(shí)候,同時(shí)要調(diào)用 [[RCIM sharedRCIM] refreshUserInfoCache:user withUserId:x.member_id];刷新緩存的userInfo。。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,351評(píng)論 25 708
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,692評(píng)論 4 61
  • 點(diǎn)擊查看原文 Web SDK 開(kāi)發(fā)手冊(cè) SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個(gè)完善的 IM 系統(tǒng)...
    layjoy閱讀 14,441評(píng)論 0 15
  • 查大大曾說(shuō):女人有三次機(jī)會(huì)改變命運(yùn)———上學(xué)頂尖,老公一流,三折騰自己,不斷受挫并成長(zhǎng)!我與多數(shù)人一般,屬于后者!...
    恒可咿呀閱讀 384評(píng)論 0 0
  • Class:定義Ivar:定義對(duì)象的實(shí)例變量,包括類型和名字。Protocol:定義正式協(xié)議。objc_prope...
    阿茲爾閱讀 181評(píng)論 0 0

友情鏈接更多精彩內(nèi)容