因為項目以前的環信,是要用到環信的EaseUI的。所以集成的時候,只能手動導入(原因下面會說到),這里介紹的也是手動導入。
從環信官網上下來的包如圖
環信開發包
然后目錄解釋環信文檔上也有解釋
從官網上下載下來的包中分為如下五部分:
環信 iOS HyphenateSDK 開發使用(不包含實時通話功能)
環信 iOS HyphenateFullSDK 開發使用(包含實時通話功能)
環信 iOS doc SDK 相關API文檔
環信 iOS ChatUIDemo3.0 工程源碼
環信 iOS EaseUI 工程源碼
環信 iOS chatdemo-ui-3.x.x.ipa 打包的 spa
上面提過,項目中要用EaseUI,所以別看環信給了你兩個選擇,可以導入一個不包含實時通話的,可以小一點。但是環信封裝的EaseUI里面,引用的庫是包含實時通話的HyphenateFullSDK,所以 ,只能導入HyphenateFullSDK庫。。。蛋疼。
這時候有小伙伴就說,那我可以cocopod導入HyphenateFullSDK庫,然后手動導入EaseUI啊。
本人試過,結果就是,EaseUI內部會報錯方法找不到,然后你對比一下cocopod導入的HyphenateFullSDK庫比手動導入的HyphenateFullSDK庫會少幾個方法。。。少的就是那幾個報錯的方法。。。
本人pod search了一下 看了一下版本 Hyphenate 的版本是3.1.5,但是下載下來的是3.2.3。。。我有點方了。。。
然后想了一種方法,手動導入Hyphenate 但是pod EaseUI。但是有朋友說,EaseUI最好手動導入,因為有可能你會修改EaseUI,所以不建議pod。
好吧,我認命了,按環信文檔手動導入Hyphenate和EaseUI,并添加系統依賴庫。
然后,編譯失敗。。。
你可以看一下錯誤,基本就是找不到UIKit,
解決方法:在pch文件中加入UIKit,注意,OBJC千萬不要忘。
#ifdef __OBJC__#import#endif
然后再編譯,又失敗。。。
看了一下,跟項目中本身的MJ庫沖突,沒辦法,只能刪了。
然后再編譯,又錯。。。這次是我的錯,環信不支持Bitcode,記得Bitcode為NO
然后在編譯,過了,恩,Nice。
運行,然后崩了。。。
臥槽,我只是導入啊,代碼還沒開始寫那。難道是我打開的方式不對?
試了幾次,發現連Appdelegate都沒進去。。。
崩潰的地方和打印
然后上網找了一圈,看到了一位大哥說的,說出現Reason: image not found錯誤,把Hyphenate.Framework庫要改成Optional就好了,如圖下。
示例圖
改完以后,果然好了,當時心里各種感覺大哥啊。然后就開始寫代碼,但是出現一個問題,登錄的block一直不回調,但是也沒有錯誤。環信也沒有日志。。。我感覺我貌似被坑了。。。
對照了一下環信的示例demo,人家的Hyphenate.Framework也不是Optional啊。但是在Build Phases里多了一行
環信demo的Build Phases
尼瑪,坑爹啊,多的這個為毛文檔里沒有。
加上了這個,果然好了。
那位大哥,我很好奇,你是怎么用那個方法解決的。。。
對于SDK的初始化,登錄,注冊什么的 就不說了,自己看文檔去吧。
這里主要說下基于EaseUI,實現消息列表頁和聊天界面
環信默認的聊天界面
因為環信提供的聊天界面和消息列表界面,是沒有昵稱和頭像的,一般的用戶的圖片和用戶名,都是存在自己服務器的,那怎么把聊天界面中的頭像和用戶名換成自己的服務器上的數據?
方法一:從APP服務器獲取昵稱和頭像昵稱和頭像的獲取:當收到一條消息(群消息)時,得到發送者的用戶ID,然后查找手機本地數據庫是否有此用戶ID的昵稱和頭像,如沒有則調用APP服務器接口通過用戶ID查詢出昵稱和頭像,然后保存到本地數據庫和緩存,下次此用戶發來信息即可直接查詢緩存或者本地數據庫,不需要再次向APP服務器發起請求。
昵稱和頭像的更新:當點擊發送者頭像時加載用戶詳情時從APP服務器查詢此用戶的具體信息然后更新本地數據庫和緩存。當用戶自己更新昵稱或頭像時,也可以發送一條透傳消息到其他用戶和用戶所在的群,來更新該用戶的昵稱和頭像。
方法二:從消息擴展中獲取昵稱和頭像
昵稱和頭像的獲取:把用戶基本的昵稱和頭像的URL放到消息的擴展中,通過消息傳遞給接收方,當收到一條消息時,則能通過消息的擴展得到發送者的昵稱和頭像URL,然后保存到本地數據庫和緩存。當顯示昵稱和頭像時,請從本地或者緩存中讀取,不要直接從消息中把賦值拿給界面(否則當用戶昵稱改變后,同一個人會顯示不同的昵稱)。
昵稱和頭像的更新:當擴展消息中的昵稱和頭像 URI 與當前本地數據庫和緩存中的相應數據不同的時候,需要把新的昵稱保存到本地數據庫和緩存,并下載新的頭像并保存到本地數據庫和緩存。
上面是兩種環信文檔中介紹的,我采用的算是第一種(其實我感覺那種都不算。。。),就是把服務器上的昵稱和頭像填到聊天界面和消息列表界面中,表示本地數據庫什么的,一點都不知道,環信你提供了么?在demo中倒是看到了,但是那個又不在EaseUI中,而且還涉及到另一個.framework,就沒有導入。如果小伙伴有更好的方法,也可以簡信告訴我。
所以大體的思路就是,服務器請求到的數據,填到消息列表和聊天界面上。
在EaseUI中,負責消息列表的是EaseConversationListViewController這個類
負責聊天界面的是EaseMessageViewController這個類
我的做法是分別用兩個類繼承他們兩個,ChatViewController繼承EaseMessageViewController,ChatListViewController繼承EaseConversationListViewController。
然后在我繼承的這個兩個類中實現環信提供的代理方法,盡量不去改環信的EaseUI代碼(里面那代碼改起來也的瘋啊,而且那么多,以后自己改的那些你還記得么?,還不如整一個新類)。
先說消息列表,有這幾需求
需求:
1、昵稱和頭像
2、消息的時間,因為EaseUI默認的是日期,而不是幾點幾分
3、下拉刷新和空視圖
4、點擊推出的聊天詳情
解決方案:
1、昵稱和頭像
EaseUI已經給我們提供了代理方法,只要實現代理方法,就可以自定義cell的樣式了。方法名:
- (id)conversationListViewController:(EaseConversationListViewController *)conversationListViewController modelForConversation:(EMConversation *)conversation
此代理是在EaseConversationListViewControllerDataSource協議中的,所以ChatListViewController(繼承EaseConversationListViewController的類)要遵從協議,并且self.dataSource = self;
此方法是返回一個遵從IConversationModel代理的model,這個model就是cell的數據源,EaseUI已經幫我們寫好了一個model,我們直接創建,然后賦值就好了
- (id)conversationListViewController:(EaseConversationListViewController *)conversationListViewController? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? modelForConversation:(EMConversation *)conversation{? ? //用環信提供的model就可以了? ? EaseConversationModel *model = [[EaseConversationModel alloc] initWithConversation:conversation];? ? //然后根據用戶名? 往上面賦值? ? //self.imageAndNameArray為自定義的數組,其中存儲的是從自己服務器上請求下來的數據? ? //數據包括,昵稱,頭像和默認圖片for(HPChatListDataModel *dataModelinself.imageAndNameArray) {if([dataModel.mobile isEqualToString:model.conversation.conversationId]) {//根據用戶名對應起來? ? ? ? ? ? model.avatarURLPath = dataModel.pic;//頭像的網絡圖片? ? ? ? ? ? model.avatarImage = [dataModel getDefaultImage];//頭像的默認圖片? ? ? ? ? ? model.title = dataModel.name;//昵稱? ? ? ? }? ? }returnmodel;}
主要是在那個for循環中,給model賦值,就好了
但是這里有個問題,如果你們服務器返回的頭像是圓的,那么會看起來頭像四角是灰色的,這是因為環信的消息列表中,頭像的imageView的背景顏色,設置成灰色的,所以,只能在EaseConversationListViewController類的
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
方法中加上,
cell.avatarView.imageView.backgroundColor = [UIColor whiteColor];
2、消息的時間
環信提供的方法:
- (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
方法的實現:
//時間- (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController? ? ? latestMessageTimeForConversationModel:(id)conversationModel{? ? NSString *latestMessageTime = @"";? ? EMMessage *lastMessage = [conversationModel.conversation latestMessage];;if(lastMessage) {? ? ? ? //這個方法是環信提供的? ? ? ? latestMessageTime = [NSDate formattedTimeFromTimeInterval:lastMessage.timestamp];? ? }returnlatestMessageTime;}
其中方法formattedTimeFromTimeInterva是環信EaseUI中提供的,要包含頭文件
#import "NSDate+Category.h"http://環信時間分類
3、下拉刷新和空視圖
//打開下來刷新
self.showRefreshHeader = YES;
實現下拉刷新的方法,
//下拉刷新? 實現以下
- (void)tableViewDidTriggerHeaderRefresh{
//super必須要有? 要不會有問題
[super tableViewDidTriggerHeaderRefresh];
//這里寫下拉的方法
}
空視圖
判斷是否為空視圖的話,直接判斷self.dataArray.count就好了,父類的數據源數組就是這個。
4、點擊推出的聊天詳情
因為聊天詳情要用我們自定義的ChatViewController(繼承于EaseMessageViewController),所以點擊推出的應該是我們自定義的,所以要實現代理方法:
- (void)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
didSelectConversationModel:(id)conversationModel;
實現:
- (void)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
didSelectConversationModel:(id)conversationModel{
EaseConversationModel *model = (EaseConversationModel *)conversationModel;
//自定義點擊cell推出的viewcontroller
ChatViewController *viewController = [HPChatViewController chatViewControllerWithConversationChatter:model.conversation.conversationId title:model.title imageUrl:model.avatarURLPath defaultImage:model.avatarImage];
[self.navigationController pushViewController:viewController animated:YES];
}
聊天界面
需求:
1、替換昵稱和頭像
2、去掉多余的功能按鈕
環信EaseUI提供的方法
- (id)messageViewController:(EaseMessageViewController *)viewController
modelForMessage:(EMMessage *)message
實現:
- (id)messageViewController:(EaseMessageViewController *)viewController? ? ? ? ? ? ? ? ? ? ? ? ? modelForMessage:(EMMessage *)message{//用戶可以根據自己的用戶體系,根據message設置用戶昵稱和頭像id model = nil;//EaseMessageModel是環信EaseUI提供的model? 直接引用就好了model = [[EaseMessageModel alloc] initWithMessage:message];//分兩種情況? 一種是當為當前用戶的時候if([model.nickname isEqualToString:[EMClient sharedClient].currentUsername]) {//默認圖model.avatarImage = [UIImage imageNamed:@"DefaultImg"]//網絡圖model.avatarURLPath = accInfo.pic;? ? }else{//當為對方的時候model.avatarURLPath = _imageUrl;//網絡圖model.avatarImage =? [UIImage imageNamed:@"DefaultImg"];? ? }? ? model.nickname = nil;//用戶昵稱returnmodel;}
2、去掉多余的功能按鈕
//刪除電話和視頻//這里為什么要移除3兩次,因為執行第一次后,后一個的索引變成了3[self.chatBarMoreView removeItematIndex:3];? ? [self.chatBarMoreView removeItematIndex:3];
好了 完成
對了,我這里的聊天界面,只是支持單聊,以后項目如果支持群組的話 ,那再來更新