網(wǎng)易云信IM已讀回執(zhí)開(kāi)發(fā)總結(jié)

1.網(wǎng)易云信

網(wǎng)易云信算是國(guó)內(nèi)比較老牌的IM即時(shí)通訊服務(wù)商了棍鳖,公司項(xiàng)目里集成的網(wǎng)易云信SDK汁针,關(guān)于這個(gè)SDK就不多說(shuō)了,官網(wǎng)上的介紹比較詳細(xì)津辩。

項(xiàng)目里接入了SDK拆撼,然后UI界面是使用的網(wǎng)易提供的一套UI框架容劳,叫NIMKit.h 在此基礎(chǔ)上進(jìn)行開(kāi)發(fā)。

2.IM已讀回執(zhí)

IM已讀回執(zhí)闸度,整個(gè)的過(guò)程簡(jiǎn)單說(shuō)來(lái)就是:

1.聊天消息的發(fā)送方竭贩,發(fā)出的一條帶開(kāi)通回執(zhí)功能的消息(可以是文字,圖片等等莺禁,語(yǔ)音一般都自帶回執(zhí))留量;
2.聊天接收方查看了(前提是收到了該消息)了這條消息,要告訴發(fā)送方我我已經(jīng)查看了哟冬,此時(shí)發(fā)一條該消息已讀的指令給發(fā)送方楼熄;
3.聊天發(fā)送方,收到接收方浩峡,發(fā)來(lái)的消息已讀回執(zhí)可岂。這個(gè)時(shí)候,就要更新本地?cái)?shù)據(jù)翰灾,在UI界面上把那條聊天信息缕粹,顯示為已讀;

群聊也是如此纸淮,在群聊中發(fā)出一條消息平斩,通過(guò)回執(zhí)功能可以看出誰(shuí)已讀或者未讀。
如果你用過(guò)釘釘咽块,就很好理解這個(gè)流程绘面。

3.前期準(zhǔn)備

既然是迭代開(kāi)發(fā),沒(méi)玩過(guò)這個(gè)SDK肯定是要查看開(kāi)發(fā)文檔的糜芳。
NIMKit文檔
單聊文檔
群聊文檔

敲黑板飒货,劃重點(diǎn),要考G涂ⅰ!
網(wǎng)易云信SDK晃虫,已讀回執(zhí)功能皆撩,需要單獨(dú)開(kāi)通服務(wù),而且是付費(fèi)服務(wù)
也就是說(shuō)哲银,代碼寫(xiě)的再好扛吞,不花錢(qián)開(kāi)通也沒(méi)吊用。

臥槽.png

講到這里荆责,其實(shí)最最首要的任務(wù)是:充錢(qián)滥比,充錢(qián),充錢(qián)做院!

4.拿起鍵盤(pán)就是干

就是干

4.1 聊天Cell定制

如下圖盲泛,NIMKit里面已經(jīng)封裝好了一套聊天Cell濒持。根據(jù)業(yè)務(wù)需要自行調(diào)整。


cell結(jié)構(gòu)

比如寺滚,它的readLabel是放在最左側(cè)柑营,我們需求是放在底部位置。所以自行重定義布局村视,很簡(jiǎn)單代碼就不貼了官套。

當(dāng)然NIMKitConfig里面你要自定義好readLabel的字體大小顏色,內(nèi)容等等蚁孔。
NIMMessageModel是每一條聊天消息的model實(shí)體奶赔,readlabel的隱藏顯示是由shouldShowReadLabel這個(gè)屬性來(lái)驅(qū)動(dòng)。

NIMSessionTableAdapter這個(gè)類(lèi)用來(lái)負(fù)責(zé)聊天頁(yè)面的tableview相關(guān)杠氢,因?yàn)樾枨笫菍⒁炎x放到了消息底部纺阔,那必然要對(duì)cell的高度進(jìn)行調(diào)整。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CGFloat cellHeight = 0;
    id modelInArray = [[self.interactor items] objectAtIndex:indexPath.row];
    if ([modelInArray isKindOfClass:[NIMMessageModel class]]) {
        NIMMessageModel *model          = (NIMMessageModel *)modelInArray;
        CGSize size                     = [model contentSize:tableView.nim_width];
        UIEdgeInsets contentViewInsets  = model.contentViewInsets;
        UIEdgeInsets bubbleViewInsets   = model.bubbleViewInsets;
        CGFloat unreadLabelHeight       = [model.message.from isEqualToString:[NIMSDK sharedSDK].loginManager.currentAccount] ? 20 : 0;// 高度適配
        cellHeight                      = size.height + contentViewInsets.top + contentViewInsets.bottom + bubbleViewInsets.top + bubbleViewInsets.bottom + unreadLabelHeight;
    }
  ....
}

4.2 P2P聊天

P2P就是點(diǎn)對(duì)點(diǎn)聊天修然,就是單聊笛钝。

在會(huì)話界面中調(diào)用發(fā)送已讀回執(zhí)的接口并傳入最后一條消息,即表示這之前的消息都已讀愕宋,對(duì)端將收到此回執(zhí)玻靡。
發(fā)送已讀回執(zhí)

@protocol NIMChatManager <NSObject>
- (void)sendMessageReceipt:(NIMMessageReceipt *)receipt
                completion:(NIMSendMessageReceiptBlock)completion;
@end

接受已讀回執(zhí)

@protocol NIMChatManagerDelegate <NSObject>
- (void)onRecvMessageReceipts:(NSArray<NIMMessageReceipt *> *)receipts;
@end

文檔里說(shuō)了這些,所有只要在生命周期方法里中贝,把最后一條消息撈出來(lái)囤捻,調(diào)一下sendMessageReceipt方法即可。
如果發(fā)送了回執(zhí)邻寿,對(duì)方的onRecvMessageReceipts就會(huì)被調(diào)用蝎土。網(wǎng)易牛逼的地方就是,收到回執(zhí)的時(shí)候绣否,SDK內(nèi)部已經(jīng)把數(shù)據(jù)都處理好了誊涯,上層只需要把UI刷新一下即可。
什么蒜撮?你問(wèn)我怎么刷新暴构??
在onRecvMessageReceipts里[self.tableView reloadData];
爽不爽段磨?

4.3 群聊發(fā)送已讀回執(zhí)

群聊和單聊方法基本差不多取逾,但是要改一個(gè)屬性,

發(fā)送需要標(biāo)記已讀回執(zhí)的群組消息標(biāo)記

/**
*  其他群成員收到此消息是否需要發(fā)送已讀回執(zhí)
*  @discussion 默認(rèn)為NO苹支,設(shè)置成 YES 之后所有群回執(zhí)相關(guān)操作才會(huì)生效
*/
@property (nonatomic,assign) BOOL teamReceiptEnabled;

一句話搞定
[NIMSDKConfig sharedConfig].teamReceiptEnabled = YES;

消息接收方收到消息砾隅,并回復(fù)回執(zhí) 在會(huì)話界面中調(diào)用發(fā)送已讀回執(zhí)的接口并傳入最后一條消息,即表示這之前的消息都已讀债蜜,對(duì)端將收到此回執(zhí)晴埂。

@protocol NIMChatManager <NSObject>
- (void)sendMessageReceipt:(NIMMessageReceipt *)receipt
                completion:(NIMSendMessageReceiptBlock)completion;
@end

到這里就遇到坑了究反,屬性都配置好了,發(fā)回執(zhí)就是不行邑时。后來(lái)咨詢了網(wǎng)易的技術(shù)支持奴紧,他丟給了我一個(gè)鏈接https://faq.yunxin.163.com/kb/main/#/item/KB0335
原來(lái)網(wǎng)易還有知識(shí)寶庫(kù)這玩意

image.png

原來(lái)不只是要將NIMSDKConfig的teamReceiptEnabled要改成YES晶丘,NIMMessage中的setting中的teamReceiptEnabled也要改成YES黍氮,這個(gè)文檔里居然沒(méi)寫(xiě)。要不是技術(shù)支持發(fā)給我誰(shuí)知道有這玩意浅浮?沫浆??

#pragma mark - NIMChatManagerDelegate
- (void)willSendMessage:(NIMMessage *)message {
 
    id<NIMSessionInteractor> interactor = self.interactor;
    if (message.session.sessionType == NIMSessionTypeTeam) {
        message.setting.teamReceiptEnabled = YES; // 設(shè)置里打開(kāi)才行滚秩。
    }
....
}

這樣之后才能正確發(fā)送已讀回執(zhí)专执。

發(fā)送已讀回執(zhí)之后,對(duì)方的那條消息郁油,就能看到
model.message.teamReceiptInfo.unreadCount就能再UI上顯示多少人未讀本股。

4.4 群聊查看消息已讀未讀列表

SDK里面已提供了查詢消息已讀id列表接口
查詢?cè)斍榻涌?br> 包括已讀人數(shù)的 id 和 未讀人數(shù)的 id 列表。需要注意查詢?cè)斍閷?duì)象不會(huì)跟著回執(zhí)人數(shù)變化而變化桐腌,如果要獲取最新的詳情拄显,必須再次調(diào)用此接口。

@protocol NIMChatManagerDelegate <NSObject>

/**
 *  查詢?nèi)航M消息回執(zhí)詳情
 *
 *  @param NIMMessage    要查詢的消息
 *  @discussion          詳情包括已讀人數(shù)的 id 列表和未讀人數(shù)的 id 列表
 *                       查詢?cè)斍閷?duì)象不會(huì)跟著回執(zhí)人數(shù)變化而變化案站,如果要獲取最新的詳情躬审,必須再次調(diào)用此接口
 *
 */
- (void)queryMessageReceiptDetail:(NIMMessage *)message
                       completion:(NIMQueryReceiptDetailBlock)completion;

@end

參數(shù)正確之后,會(huì)返回這條消息的已讀id列表和未讀id列表蟆盐,列表里面保存的是userid承边。

這里也遇到一個(gè)坑:
在聊天界面,當(dāng)前新發(fā)送的消息石挂,能夠查詢到已讀未讀列表博助。但是打開(kāi)頁(yè)面之前的歷史消息,無(wú)論如何都查不到誊稚。
經(jīng)過(guò)debug發(fā)現(xiàn)翔始,當(dāng)退出聊天窗口,所有的消息變成歷史數(shù)據(jù)之后里伯,才進(jìn)入聊天窗口,所有的歷史消息message.setting.teamReceiptEnabled統(tǒng)統(tǒng)變成了NO渤闷,解決方法也很簡(jiǎn)單疾瓮,每次queryMessageReceiptDetail查詢之前,再把這個(gè)屬性設(shè)置成YES就能正確查詢列表了飒箭。

注意點(diǎn):網(wǎng)易云信最多支持100人群聊的已讀消息回執(zhí)
超過(guò)100也就不支持了狼电,如果不能滿足需求蜒灰,要么有本事自己寫(xiě)一套IM,要么就換一家SDK吧肩碟。

5.結(jié)束語(yǔ)

雖然是第一次接觸强窖,總體覺(jué)得網(wǎng)易這整個(gè)一套IM的SDK也不是很難,嵌套的比較多削祈,需要認(rèn)真梳理各個(gè)類(lèi)各個(gè)協(xié)議翅溺,所承載的功能。其次髓抑,開(kāi)發(fā)難免會(huì)遇到一些坑和彎路咙崎,寫(xiě)這篇文章也算是為了幫后來(lái)人吧。

如有錯(cuò)誤吨拍,還請(qǐng)各位看官批評(píng)指正~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末褪猛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子羹饰,更是在濱河造成了極大的恐慌伊滋,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件队秩,死亡現(xiàn)場(chǎng)離奇詭異笑旺,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)刹碾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)燥撞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人迷帜,你說(shuō)我怎么就攤上這事物舒。” “怎么了戏锹?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵冠胯,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我锦针,道長(zhǎng)荠察,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任奈搜,我火速辦了婚禮悉盆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘馋吗。我一直安慰自己焕盟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布宏粤。 她就那樣靜靜地躺著脚翘,像睡著了一般灼卢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上来农,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天鞋真,我揣著相機(jī)與錄音,去河邊找鬼沃于。 笑死涩咖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的揽涮。 我是一名探鬼主播抠藕,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蒋困!你這毒婦竟也來(lái)了盾似?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤雪标,失蹤者是張志新(化名)和其女友劉穎零院,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體村刨,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡告抄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嵌牺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片打洼。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖逆粹,靈堂內(nèi)的尸體忽然破棺而出募疮,到底是詐尸還是另有隱情,我是刑警寧澤僻弹,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布阿浓,位于F島的核電站,受9級(jí)特大地震影響蹋绽,放射性物質(zhì)發(fā)生泄漏芭毙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一卸耘、第九天 我趴在偏房一處隱蔽的房頂上張望退敦。 院中可真熱鬧,春花似錦蚣抗、人聲如沸苛聘。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)设哗。三九已至,卻和暖如春两蟀,著一層夾襖步出監(jiān)牢的瞬間网梢,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工赂毯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留战虏,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓党涕,卻偏偏與公主長(zhǎng)得像烦感,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子膛堤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容