環(huán)信3.0ios客戶端的集成(十三)

版本記錄

版本號 時間
V1.0 2017.06.10

前言

很多app種都集成環(huán)信做第三方信息通訊工具漩勤,這里我們就看一下環(huán)信的主要功能和集成方法焕妙。先給出環(huán)信3.0的地址盯腌。
感興趣的可以參考:
1. 環(huán)信ios客戶端的集成(一)
2. 環(huán)信ios客戶端的集成(二)
3. 環(huán)信ios客戶端的集成(三)
4. 環(huán)信ios客戶端的集成(四)
5. 環(huán)信ios客戶端的集成(五)
6. 環(huán)信ios客戶端的集成(六)
7. 環(huán)信ios客戶端的集成(七)
8. 環(huán)信ios客戶端的集成(八)
9. 環(huán)信ios客戶端的集成(九)
10. 環(huán)信ios客戶端的集成(十)
11. 環(huán)信ios客戶端的集成(十一)
12. 環(huán)信ios客戶端的集成(十二)
這一篇主要說一下環(huán)信的 EaseUI 使用

一、簡介

EaseUI 封裝了 IM 功能常用的控件(如聊天會話鬼譬、會話列表娜膘、聯(lián)系人列表)。旨在幫助開發(fā)者快速集成環(huán)信 SDK优质。

源碼地址:


二竣贪、視頻教程

以下是EaseUI集成參考視頻,您可以通過視頻學習如何集成環(huán)信SDK巩螃。


三演怎、快速集成

1. 方法一:

  • 通過 Cocoapods 來集成 EaseUI:
//集成環(huán)信SDK
pod 'Hyphenate'
//集成環(huán)信EaseUI
pod 'EaseUI', :git => 'https://github.com/easemob/easeui-ios-hyphenate-cocoapods.git'

注意: 由于SDK改成了動態(tài)庫,EaseUI引入的頭文件Full版本和Lite版本不同避乏,導致集成EaseUI失敗爷耀。代碼中包含了宏ENABLE_LITE的定義這個是為了區(qū)分集成Lite版本SDK還是Full版本SDK,當通過pod在集成EaseUILite時會在Build Settings> GCC_PREPROCESSOR_DEFINITIONS >ENABLE_LITE=1中定義ENABLE_LITE淑际,集成EaseUI時則不會定義畏纲,所以開發(fā)者不需要關(guān)注這個字段,如果集成Lite版本SDK春缕,建議使用

//集成環(huán)信Lite版SDK
pod 'HyphenateLite'
//集成環(huán)信EaseUI
pod 'EaseUILite', :git =>'https://github.com/easemob/easeui-ios-hyphenate-cocoapods.git'

2.方法二:

  • 集成 EaseUI 前盗胀,首先需要集成環(huán)信 iOS SDK,參考:集成文檔锄贼。
  • 參考ChatDemo3.0 導入的方式,直接將EaseUI拖入已經(jīng)集成SDK的項目中票灰。

四、初始化

第 1 步:引入相關(guān)頭文件 #import “EaseUI.h”宅荤。

第 2 步:在工程的 AppDelegate 中的以下方法中屑迂,調(diào)用 EaseUI 對應方法。(注: 此方法不需要重復調(diào)用)

[[EaseSDKHelper shareHelper] hyphenateApplication:application
                    didFinishLaunchingWithOptions:launchOptions
                                               appkey:appkey
                                     apnsCertName:apnsCertName
                                      otherConfig:@{kSDKConfigEnableConsoleLogger:[NSNumber numberWithBool:YES]}];


五冯键、聊天會話

創(chuàng)建聊天會話惹盼、傳遞用戶或群 ID 和會話類型(EMConversationType)。

EaseMessageViewController *chatController = [[EaseMessageViewController alloc] initWithConversationChatter:@"8001" conversationType:EMConversationTypeChat];


六惫确、聊天頁面刷新

EaseRefreshTableViewController提供了列表上拉加載手报、下拉刷新(加載)功能的UIViewController,其中已添加控件UITableView改化,默認未開啟上拉加載掩蛤、下來刷新(加載)的功能

1.實現(xiàn)上拉加載功能

繼承自EaseRefreshTableViewController的子類,開啟上拉加載需要設(shè)置showRefreshFooter為YES陈肛,并重寫父類方法- (void)tableViewDidTriggerFooterRefresh;揍鸟,如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // Do any additional setup after loading the view.
    self.showRefreshFooter = YES;
}

- (void)tableViewDidTriggerFooterRefresh {
   //子類需要重寫此方法
   
}

2.實現(xiàn)下拉加載(刷新)功能

繼承自EaseRefreshTableViewController的子類,開啟下拉加載(刷新)需要設(shè)置showRefreshHeader為YES句旱,并重寫父類方法- (void)tableViewDidTriggerHeaderRefresh;阳藻,如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // Do any additional setup after loading the view.
    self.showRefreshHeader = YES;
}

- (void)tableViewDidTriggerHeaderRefresh {
   //子類需要重寫此方法
   
}

七、聊天會話功能擴展

EaseUI 提供現(xiàn)成的聊天會話 ViewController前翎,可以通過繼承 EaseMessageViewController 方式(參考 ChatDemo-UI3.0 中 ChatViewController)實現(xiàn)對聊天會話的擴展稚配。也可以直接使用 EaseMessageViewController,通過 EaseMessageViewControllerDelegate 和 EaseMessageViewControllerDataSource 兩個協(xié)議實現(xiàn)對 EaseMessageViewController 的擴展港华。

1.實現(xiàn)自定義聊天樣式

EaseMessageViewControllerDelegate

獲取自定義消息 cell道川,根據(jù) messageModel,用戶自己判斷是否顯示自定義消息 cell立宜。如果返回 nil 會顯示默認冒萄;如果返回 cell 會顯示用戶自定義消息cell。

/*!
 @method
 @brief 獲取消息自定義cell
 @discussion 用戶根據(jù)messageModel判斷是否顯示自定義cell橙数。返回nil顯示默認cell尊流,否則顯示用戶自定義cell
 @param tableView 當前消息視圖的tableView
 @param messageModel 消息模型
 @result 返回用戶自定義cell
 */
- (UITableViewCell *)messageViewController:(UITableView *)tableView
                       cellForMessageModel:(id<IMessageModel>)messageModel;

/*!
 @method
 @brief 獲取消息cell高度
 @discussion 用戶根據(jù)messageModel判斷,是否自定義顯示cell的高度
 @param viewController 當前消息視圖
 @param messageModel 消息模型
 @param cellWidth 視圖寬度
 @result 返回用戶自定義cell
 */
- (CGFloat)messageViewController:(EaseMessageViewController *)viewController
           heightForMessageModel:(id<IMessageModel>)messageModel
                   withCellWidth:(CGFloat)cellWidth;
                   
//具體創(chuàng)建自定義Cell的樣例:
- (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id<IMessageModel>)model
{
    //樣例為如果消息是文本消息顯示用戶自定義cell
    if (model.bodyType == eMessageBodyType_Text) {
        NSString *CellIdentifier = [CustomMessageCell cellIdentifierWithModel:model];
        //CustomMessageCell為用戶自定義cell,繼承了EaseBaseMessageCell
        CustomMessageCell *cell = (CustomMessageCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[CustomMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier model:model];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
        }
        cell.model = model;
        return cell;
    }
    return nil;
}

- (CGFloat)messageViewController:(EaseMessageViewController *)viewController
           heightForMessageModel:(id<IMessageModel>)messageModel
                   withCellWidth:(CGFloat)cellWidth
{
    //樣例為如果消息是文本消息使用用戶自定義cell的高度
    if (messageModel.bodyType == EMMessageBodyTypeText) {
        //CustomMessageCell為用戶自定義cell,繼承了EaseBaseMessageCell
        return [CustomMessageCell cellHeightWithModel:messageModel];
    }
    return 0.f;
}

下面是效果圖

效果圖

選中消息的回調(diào)


/*!
 @method
 @brief 選中消息的回調(diào)
 @discussion 用戶根據(jù)messageModel判斷灯帮,是否自定義處理消息選中時間崖技。返回YES為自定義處理逻住,返回NO為默認處理
 @param viewController 當前消息視圖
 @param messageModel 消息模型
 @result 是否采用自定義處理
 */
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
        didSelectMessageModel:(id<IMessageModel>)messageModel;
        
//選中消息回調(diào)的樣例:
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
        didSelectMessageModel:(id<IMessageModel>)messageModel
{
    BOOL flag = NO;
    //樣例為如果消息是文件消息用戶自定義處理選中邏輯
    switch (messageModel.bodyType) {
        case EMMessageBodyTypeImage:
        case EMMessageBodyTypeLocation:
        case EMMessageBodyTypeVideo:
        case EMMessageBodyTypeVoice:
            break;
        case EMMessageBodyTypeFile:
        {
            flag = YES;
            NSLog(@"用戶自定義實現(xiàn)");
        }
            break;
        default:
            break;
    }
    return flag;
}

用戶選中頭像的回調(diào)


/*!
 @method
 @brief 點擊消息頭像
 @discussion 獲取用戶點擊頭像回調(diào)
 @param viewController 當前消息視圖
 @param messageModel 消息模型
 @result
 */
- (void)messageViewController:(EaseMessageViewController *)viewController
    didSelectAvatarMessageModel:(id<IMessageModel>)messageModel;
    
//獲取用戶點擊頭像回調(diào)的樣例:
- (void)messageViewController:(EaseMessageViewController *)viewController
   didSelectAvatarMessageModel:(id<IMessageModel>)messageModel
{
    //UserProfileViewController用戶自定義的個人信息視圖
    //樣例的邏輯是選中消息頭像后,進入該消息發(fā)送者的個人信息
    UserProfileViewController *userprofile = [[UserProfileViewController alloc] initWithUsername:messageModel.message.from];
    [self.navigationController pushViewController:userprofile animated:YES];
}

錄音按鈕狀態(tài)的回調(diào)


/*!
 @method
 @brief 底部錄音功能按鈕狀態(tài)回調(diào)
 @discussion 獲取底部錄音功能按鈕狀態(tài)回調(diào)迎献,根據(jù)EaseRecordViewType瞎访,用戶自定義處理UI的邏輯
 @param viewController 當前消息視圖
 @param recordView 錄音視圖
 @param type 錄音按鈕當前狀態(tài)
 @result
 */
- (void)messageViewController:(EaseMessageViewController *)viewController
              didSelectRecordView:(UIView *)recordView
                withEvenType:(EaseRecordViewType)type;
                
//錄音按鈕狀態(tài)的回調(diào)樣例:
- (void)messageViewController:(EaseMessageViewController *)viewController
          didSelectRecordView:(UIView *)recordView
                 withEvenType:(EaseRecordViewType)type
{
    /*
        EaseRecordViewTypeTouchDown,//錄音按鈕按下
        EaseRecordViewTypeTouchUpInside,//手指在錄音按鈕內(nèi)部時離開
        EaseRecordViewTypeTouchUpOutside,//手指在錄音按鈕外部時離開
        EaseRecordViewTypeDragInside,//手指移動到錄音按鈕內(nèi)部
        EaseRecordViewTypeDragOutside,//手指移動到錄音按鈕外部
    */
    //根據(jù)type類型,用戶自定義處理UI的邏輯
    switch (type) {
        case EaseRecordViewTypeTouchDown:
        {
            if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
                [(EaseRecordView *)self.recordView  recordButtonTouchDown];
            }
        }
            break;
        case EaseRecordViewTypeTouchUpInside:
        {
            if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
                [(EaseRecordView *)self.recordView recordButtonTouchUpInside];
            }
            [self.recordView removeFromSuperview];
        }
            break;
        case EaseRecordViewTypeTouchUpOutside:
        {
            if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
                [(EaseRecordView *)self.recordView recordButtonTouchUpOutside];
            }
            [self.recordView removeFromSuperview];
        }
            break;
        case EaseRecordViewTypeDragInside:
        {
            if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
                [(EaseRecordView *)self.recordView recordButtonDragInside];
            }
        }
            break;
        case EaseRecordViewTypeDragOutside:
        {
            if ([self.recordView isKindOfClass:[EaseRecordView class]]) {
                [(EaseRecordView *)self.recordView recordButtonDragOutside];
            }
        }
            break;
        default:
            break;
    }
}

EaseMessageViewControllerDataSource

用戶判斷消息是否允許長按吁恍,返回布爾值扒秸;如果用戶允許長按,此方法為通知用戶觸發(fā)長按手勢冀瓦,返回布爾值伴奥,如果返回 NO 默認方式處理,返回 YES 采用用戶自定義的處理方式翼闽。

/*!
 @method
 @brief 是否允許長按
 @discussion 獲取是否允許長按的回調(diào)拾徙,默認是NO
 @param viewController 當前消息視圖
 @param indexPath 長按消息對應的indexPath
 @result
 */
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
   canLongPressRowAtIndexPath:(NSIndexPath *)indexPath;

/*!
 @method
 @brief 觸發(fā)長按手勢
 @discussion 獲取觸發(fā)長按手勢的回調(diào),默認是NO
 @param viewController 當前消息視圖
 @param indexPath 長按消息對應的indexPath
 @result
 */
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
   didLongPressRowAtIndexPath:(NSIndexPath *)indexPath;
   
//長按收拾回調(diào)樣例:
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
   canLongPressRowAtIndexPath:(NSIndexPath *)indexPath
{
    //樣例給出的邏輯是所有cell都允許長按
    return YES;
}

- (BOOL)messageViewController:(EaseMessageViewController *)viewController
   didLongPressRowAtIndexPath:(NSIndexPath *)indexPath
{
    //樣例給出的邏輯是長按cell之后顯示menu視圖
    id object = [self.dataArray objectAtIndex:indexPath.row];
    if (![object isKindOfClass:[NSString class]]) {
        EaseMessageCell *cell = (EaseMessageCell *)[self.tableView cellForRowAtIndexPath:indexPath];
        [cell becomeFirstResponder];
        self.menuIndexPath = indexPath;
        [self _showMenuViewController:cell.bubbleView andIndexPath:indexPath messageType:cell.model.bodyType];
    }
    return YES;
}

Demo3.0實現(xiàn)的消息長按效果演示:

長按效果展示

將EMMessage類型轉(zhuǎn)換為符合<IMessageModel>協(xié)議的類型肄程,設(shè)置用戶信息锣吼,消息顯示用戶昵稱和頭像。

/*!
 @method
 @brief 將EMMessage類型轉(zhuǎn)換為符合<IMessageModel>協(xié)議的類型
 @discussion 將EMMessage類型轉(zhuǎn)換為符合<IMessageModel>協(xié)議的類型,設(shè)置用戶信息,消息顯示用戶昵稱和頭像
 @param viewController 當前消息視圖
 @param EMMessage 聊天消息對象類型
 @result 返回<IMessageModel>協(xié)議的類型
 */
- (id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController
                           modelForMessage:(EMMessage *)message;
                           
//具體樣例:
- (id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController
                           modelForMessage:(EMMessage *)message
{
    //用戶可以根據(jù)自己的用戶體系蓝厌,根據(jù)message設(shè)置用戶昵稱和頭像
    id<IMessageModel> model = nil;
    model = [[EaseMessageModel alloc] initWithMessage:message];
    model.avatarImage = [UIImage imageNamed:@"EaseUIResource.bundle/user"];//默認頭像
    model.avatarURLPath = @"";//頭像網(wǎng)絡地址
    model.nickname = @"昵稱";//用戶昵稱
    return model;
}

聊天會話頁面頭像和昵稱的效果演示:

效果圖

2. 聊天會話樣式自定義

聊天樣式的自定義需要在 EaseMessageViewController 中 viewDidload 結(jié)束前設(shè)置玄叠。
@property中帶有UI_APPEARANCE_SELECTOR,都可以通過set的形式設(shè)置樣式拓提,具體可以參考EaseBaseMessageCell.h,EaseMessageCell.h

發(fā)送氣泡圖片設(shè)置

[[EaseBaseMessageCell appearance] setSendBubbleBackgroundImage:[[UIImage imageNamed:@"chat_sender_bg"] stretchableImageWithLeftCapWidth:5 topCapHeight:35]];//設(shè)置發(fā)送氣泡

[[EaseBaseMessageCell appearance] setRecvBubbleBackgroundImage:[[UIImage imageNamed:@"chat_receiver_bg"] stretchableImageWithLeftCapWidth:35 topCapHeight:35]];//設(shè)置接收氣泡

頭像設(shè)置

[[EaseBaseMessageCell appearance] setAvatarSize:40.f];//設(shè)置頭像大小

[[EaseBaseMessageCell appearance] setAvatarCornerRadius:20.f];//設(shè)置頭像圓角

消息字體顏色設(shè)置

[[EaseMessageCell appearance] setMessageTextFont:[UIFont systemFontOfSize:15]];//消息顯示字體

[[EaseMessageCell appearance] setMessageTextColor:[UIColor blackColor]];//消息顯示顏色

[[EaseMessageCell appearance] setMessageLocationFont:[UIFont systemFontOfSize:12]];//位置消息顯示字體

[[EaseMessageCell appearance] setMessageLocationColor:[UIColor whiteColor]];//位置消息顯示顏色

語音消息圖片樣式設(shè)置

[[EaseBaseMessageCell appearance] setSendMessageVoiceAnimationImages:@[[UIImage imageNamed:@"EaseUIResource.bundle/chat_sender_audio_playing_full"], [UIImage imageNamed:@"EaseUIResource.bundle/chat_sender_audio_playing_000"], [UIImage imageNamed:@"EaseUIResource.bundle/chat_sender_audio_playing_001"], [UIImage imageNamed:@"EaseUIResource.bundle/chat_sender_audio_playing_002"], [UIImage imageNamed:@"EaseUIResource.bundle/chat_sender_audio_playing_003"]]];//發(fā)送者語音消息播放圖片

[[EaseBaseMessageCell appearance] setRecvMessageVoiceAnimationImages:@[[UIImage imageNamed:@"EaseUIResource.bundle/chat_receiver_audio_playing_full"],[UIImage imageNamed:@"EaseUIResource.bundle/chat_receiver_audio_playing000"], [UIImage imageNamed:@"EaseUIResource.bundle/chat_receiver_audio_playing001"], [UIImage imageNamed:@"EaseUIResource.bundle/chat_receiver_audio_playing002"], [UIImage imageNamed:@"EaseUIResource.bundle/chat_receiver_audio_playing003"]]];//接收者語音消息播放圖片

3. 聊天會話輸入框自定義

繼承EaseMessageViewController,或者EaseMessageViewController的實例調(diào)用以下方法設(shè)置底部輸入框

CustomerInputView *inputView = [[CustomerInputView alloc] init];//CustomerInputView用戶自定義底部輸入框
[self setChatToolbar:inputView];

實現(xiàn)默認底部輸入框delegate

@interface CustomerInputView : UIView

@property (weak, nonatomic) id<EMChatToolbarDelegate> delegate;

@end

自定義輸入框發(fā)送消息

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
    if ([text isEqualToString:@"\n"]){
        if(self.delegate && [self.delegate respondsToSelector:@selector(didSendText:)]) {
            [self.delegate didSendText:self.textView.text];
        }
        self.textView.text = @"";
        self.placeholderLabel.text = @"說點什么吧...";
        return NO;
    }
    return YES;
}

自定義輸入框高度變化


//這是一個舉例,初始化輸入框的時候注冊監(jiān)聽鍵盤高度變化
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:)name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:)name:UIKeyboardWillHideNotification object:nil];

- (void)keyboardWillShow:(NSNotification *)aNotification{
    //獲取鍵盤的高度
    NSValue *aValue = [[aNotification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey];
    CGRect keyboardRect = [aValue CGRectValue];
    if (keyboardRect.size.height > self.keyboardHeight) {
        self.keyboardHeight = keyboardRect.size.height;
    }
    self.frame = CGRectMake(0, _originY - self.keyboardHeight - 64, App_Width, self.inputH + self.keyboardHeight);
    if (self.delegate && [self.delegate respondsToSelector:@selector(chatToolbarDidChangeFrameToHeight:)]) {
        [self.delegate chatToolbarDidChangeFrameToHeight:self.frame.size.height];
    }
}

- (void)keyboardWillHide:(NSNotification *)aNotification{
    self.frame = CGRectMake(0, _originY - 64, App_Width, self.inputH) ;
    if (self.delegate && [self.delegate respondsToSelector:@selector(chatToolbarDidChangeFrameToHeight:)]) {
        [self.delegate chatToolbarDidChangeFrameToHeight:self.frame.size.height];
    }
}

4.聊天會話底部菜單自定義

EaseChatBarMoreView為自定義的功能菜單選擇視圖读恃,目前已添加的功能有:

/*!
 @method
 @brief 新增一個新的功能按鈕
 @discussion
 @param image 按鈕圖片
 @param highLightedImage 高亮圖片
 @param title 按鈕標題
 @result
 */
- (void)insertItemWithImage:(UIImage*)image
           highlightedImage:(UIImage*)highLightedImage
                      title:(NSString*)title;

/*!
 @method
 @brief 修改功能按鈕圖片
 @discussion
 @param image 按鈕圖片
 @param highLightedImage 高亮圖片
 @param title 按鈕標題
 @param index 按鈕索引
 @result
 */
- (void)updateItemWithImage:(UIImage*)image
           highlightedImage:(UIImage*)highLightedImage
                      title:(NSString*)title
                    atIndex:(NSInteger)index;

/*!
 @method
 @brief 根據(jù)索引刪除功能按鈕
 @discussion
 @param index 按鈕索引
 @result
 */
- (void)removeItematIndex:(NSInteger)index;

各個選項的功能需要ViewController實現(xiàn)EaseChatBarMoreViewDelegate協(xié)議中的回調(diào)方法來編寫或調(diào)整.


八、消息發(fā)送

EaseSDKHelper 封裝了發(fā)送消息的方法代态。

具體發(fā)送消息樣例:


/*
 EMChatTypeChat            單聊消息
 EMChatTypeGroupChat       群聊消息
 EMChatTypeChatRoom        聊天室消息
*/

//發(fā)送文字消息
EMMessage *message = [EaseSDKHelper sendTextMessage:@"要發(fā)送的消息"
                                                 to:@"6001"http://接收方
                                        messageType:EMChatTypeChat//消息類型
                                         messageExt:nil]; //擴展信息                                          
//發(fā)送位置消息
EMMessage *message = [EaseSDKHelper sendLocationMessageWithLatitude:35.1//經(jīng)度
                                                          longitude:35.1//緯度
                                                            address:"地址"
                                                                 to:@"6001"http://接收方
                                                        messageType:EMChatTypeChat//消息類型
                                                         messageExt:nil];//擴展信息                                         

//發(fā)送圖片消息      
EMMessage *message = [EaseSDKHelper sendImageMessageWithImageData:imageData//發(fā)送的圖片數(shù)據(jù)NSData
                                                               to:@"6001"http://接收方
                                                      messageType:EMChatTypeChat//消息類型
                                                       messageExt:nil];//擴展信息                                                    

//發(fā)送音頻消息                                           
EMMessage *message = [EaseSDKHelper sendVoiceMessageWithLocalPath:localPath//音頻本地地址
                                                         duration:duration//語音的時長寺惫,單位是秒
                                                               to:@"6001"http://接收方
                                                      messageType:EMChatTypeChat//消息類型
                                                       messageExt:nil];//擴展信息

//發(fā)送視頻文件消息
EMMessage *message = [EaseSDKHelper sendVideoMessageWithURL:url//發(fā)送的視頻地址
                                                         to:@"6001"http://接收方
                                                messageType:EMChatTypeChat//消息類型
                                                 messageExt:nil];//擴展信息

//發(fā)送構(gòu)造成功的消息                                                   
[[EMClient sharedClient].chatManager asyncSendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {

}];        


九、會話列表

1.會話列表初始化

EaseConversationListViewController *chatListVC = [[EaseConversationListViewController alloc] init];

2. 會話列表下拉刷新

需要繼承EaseConversationListViewController的子類蹦疑,在viewDidLoad中加入

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // Do any additional setup after loading the view.
    self.showRefreshHeader = YES;
    //首次進入加載數(shù)據(jù)
    [self tableViewDidTriggerHeaderRefresh];
}

3.會話列表擴展

EaseConversationListViewControllerDataSource

用戶根據(jù) conversationModel 實現(xiàn)西雀,實現(xiàn)自定義會話中最后一條消息文案的顯示內(nèi)容。

/*!
 @method
 @brief 獲取最后一條消息顯示的內(nèi)容
 @discussion 用戶根據(jù)conversationModel實現(xiàn),實現(xiàn)自定義會話中最后一條消息文案的顯示內(nèi)容
 @param conversationListViewController 當前會話列表視圖
 @param IConversationModel 會話模型
 @result 返回用戶最后一條消息顯示的內(nèi)容
 */
- (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
      latestMessageTitleForConversationModel:(id<IConversationModel>)conversationModel;


/*!
 @method
 @brief 獲取最后一條消息顯示的時間
 @discussion 用戶可以根據(jù)conversationModel,自定義實現(xiàn)會話列表中時間文案的顯示內(nèi)容
 @param conversationListViewController 當前會話列表視圖
 @param IConversationModel 會話模型
 @result 返回用戶最后一條消息時間的顯示文案
 */
- (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
       latestMessageTimeForConversationModel:(id<IConversationModel>)conversationModel;
       
//最后一條消息展示內(nèi)容樣例    
- (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
      latestMessageTitleForConversationModel:(id<IConversationModel>)conversationModel
{
    NSString *latestMessageTitle = @"";
    EMMessage *lastMessage = [conversationModel.conversation latestMessage];
    if (lastMessage) {
        EMMessageBody *messageBody = lastMessage.body;
        switch (messageBody.type) {
            case EMMessageBodyTypeImage:{
                latestMessageTitle = NSLocalizedString(@"message.image1", @"[image]");
            } break;
            case EMMessageBodyTypeText:{
                // 表情映射歉摧。
                NSString *didReceiveText = [EaseConvertToCommonEmoticonsHelper
                                            convertToSystemEmoticons:((EMTextMessageBody *)messageBody).text];
                latestMessageTitle = didReceiveText;
                if ([lastMessage.ext objectForKey:MESSAGE_ATTR_IS_BIG_EXPRESSION]) {
                    latestMessageTitle = @"[動畫表情]";
                }
            } break;
            case EMMessageBodyTypeVoice:{
                latestMessageTitle = NSLocalizedString(@"message.voice1", @"[voice]");
            } break;
            case EMMessageBodyTypeLocation: {
                latestMessageTitle = NSLocalizedString(@"message.location1", @"[location]");
            } break;
            case EMMessageBodyTypeVideo: {
                latestMessageTitle = NSLocalizedString(@"message.video1", @"[video]");
            } break;
            case EMMessageBodyTypeFile: {
                latestMessageTitle = NSLocalizedString(@"message.file1", @"[file]");
            } break;
            default: {
            } break;
        }
    }
    
    return latestMessageTitle;
}

//最后一條消息展示時間樣例  
- (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
       latestMessageTimeForConversationModel:(id<IConversationModel>)conversationModel
{
    NSString *latestMessageTime = @"";
    EMMessage *lastMessage = [conversationModel.conversation latestMessage];;
    if (lastMessage) {
        latestMessageTime = [NSDate formattedTimeFromTimeInterval:lastMessage.timestamp];
    }
    return latestMessageTime;
}

會話列表最后一條消息和時間顯示的效果演示

效果圖

EaseConversationListViewControllerDelegate

點擊會話列表用戶可以根據(jù) conversationModel 自定義處理邏輯艇肴。

/*!
 @method
 @brief 獲取點擊會話列表的回調(diào)
 @discussion 獲取點擊會話列表的回調(diào)后,點擊會話列表用戶可以根據(jù)conversationModel自定義處理邏輯
 @param conversationListViewController 當前會話列表視圖
 @param IConversationModel 會話模型
 @result
 */
- (void)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
            didSelectConversationModel:(id<IConversationModel>)conversationModel;
            
//會話列表點擊的回調(diào)樣例
- (void)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
            didSelectConversationModel:(id<IConversationModel>)conversationModel
{
    //樣例展示為根據(jù)conversationModel,進入不同的會話ViewController
        if (conversationModel) {
        EMConversation *conversation = conversationModel.conversation;
        if (conversation) {
            if ([[RobotManager sharedInstance] isRobotWithUsername:conversation.conversationId]) {
                RobotChatViewController *chatController = [[RobotChatViewController alloc] initWithConversationChatter:conversation.conversationId conversationType:conversation.type];
                chatController.title = [[RobotManager sharedInstance] getRobotNickWithUsername:conversation.conversationId];
                [self.navigationController pushViewController:chatController animated:YES];
            } else {
                ChatViewController *chatController = [[ChatViewController alloc] initWithConversationChatter:conversation.conversationId conversationType:conversation.type];
                chatController.title = conversationModel.title;
                [self.navigationController pushViewController:chatController animated:YES];
            }
        }
        [[NSNotificationCenter defaultCenter] postNotificationName:@"setupUnreadMessageCount" object:nil];
        [self.tableView reloadData];
    }
}


十叁温、聯(lián)系人列表

1.聯(lián)系人列表初始化

EaseUsersListViewController *listViewController = [[EaseUsersListViewController alloc] init];

2.聯(lián)系人列表下拉刷新

需要繼承EaseUsersListViewController的子類再悼,在viewDidLoad中加入

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // Do any additional setup after loading the view.
    self.showRefreshHeader = YES;
}

3.聯(lián)系人列表擴展

需要實現(xiàn) EMUserListViewControllerDataSource。

根據(jù) buddy 獲取用戶自定信息膝但,聯(lián)系人列表里展示昵稱和頭像冲九。

/*!
 @method
 @brief 獲取用戶模型
 @discussion 根據(jù)buddy獲取用戶自定信息,聯(lián)系人列表里展示昵稱和頭像
 @param userListViewController 當前聯(lián)系人視圖
 @param buddy 好友的信息描述類
 @result 返回用戶模型
 */
- (id<IUserModel>)userListViewController:(EaseUsersListViewController *)userListViewController
                           modelForBuddy:(NSString *)buddy;
                           
//聯(lián)系人列表擴展樣例
- (id<IUserModel>)userListViewController:(EaseUsersListViewController *)userListViewController
                           modelForBuddy:(NSString *)buddy
{
    //用戶可以根據(jù)自己的用戶體系跟束,根據(jù)buddy設(shè)置用戶昵稱和頭像
    id<IUserModel> model = nil;
    model = [[EaseUserModel alloc] initWithBuddy:buddy];
    model.avatarURLPath = @"";//頭像網(wǎng)絡地址
    model.nickname = @"昵稱";//用戶昵稱
    return model;
}

聯(lián)系人列表頭像和昵稱的效果演示:

效果圖

十一莺奸、EaseUI中使用的第三方庫

  • MBProgressHUD
  • MJRefresh
  • MWPhotoBrowser
  • SDWebImage
  • DACircularProgressView

EaseUI中第三方庫沖突問題

目前推薦Pod的方式集成EaseUI丑孩。如果集成了EaseUI,而且上述第三方依賴在開發(fā)者的代碼中也有引用灭贷,會造成沖突嚎杨,無法編譯,針對此問題有如下兩種場景:

  • 開發(fā)者使用的第三方依賴也是通過pod方式集成氧腰,這樣pod只會安裝一份,不會重復安裝多個版本刨肃。如果是依賴版本不兼容古拴,例如開發(fā)者依賴了'MBProgressHUD', '~> 1.0.0' ,而EaseUI通過MWPhotoBrowser間接依賴了'MBProgressHUD', '~> 0.9' 真友,這樣會導致pod install失敗黄痪,開發(fā)者可以改變MBProgressHUD的依賴版本。EaseUI也會在后續(xù)版本中盡量減少使用第三方依賴盔然。

  • 如果是手動導入了上述第三方庫桅打,建議直接刪除手動導入的部分,避免沖突的產(chǎn)生愈案,如果EaseUI使用第三方庫的版本不能滿足開發(fā)者的需求挺尾,開發(fā)者也可以手動將第三方庫進行重命名,保證兼容(手動方式集成EaseUI也可以參考此解決方案)站绪。

后記

??關(guān)于環(huán)信3.0所有的基本理論差不多就這么多了遭铺,下一篇主要就是結(jié)合具體示例,完成基于環(huán)信3.0的及時通信恢准。待續(xù)~~

風景圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末魂挂,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子馁筐,更是在濱河造成了極大的恐慌涂召,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件敏沉,死亡現(xiàn)場離奇詭異果正,居然都是意外死亡,警方通過查閱死者的電腦和手機赦抖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進店門舱卡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人队萤,你說我怎么就攤上這事轮锥。” “怎么了要尔?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵舍杜,是天一觀的道長新娜。 經(jīng)常有香客問我,道長既绩,這世上最難降的妖魔是什么概龄? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮饲握,結(jié)果婚禮上私杜,老公的妹妹穿的比我還像新娘。我一直安慰自己救欧,他們只是感情好衰粹,可當我...
    茶點故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著笆怠,像睡著了一般铝耻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蹬刷,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天瓢捉,我揣著相機與錄音,去河邊找鬼办成。 笑死泡态,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的迂卢。 我是一名探鬼主播兽赁,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼冷守!你這毒婦竟也來了刀崖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤拍摇,失蹤者是張志新(化名)和其女友劉穎亮钦,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體充活,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡蜂莉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了混卵。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片映穗。...
    茶點故事閱讀 40,918評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖幕随,靈堂內(nèi)的尸體忽然破棺而出蚁滋,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布辕录,位于F島的核電站睦霎,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏走诞。R本人自食惡果不足惜副女,卻給世界環(huán)境...
    茶點故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蚣旱。 院中可真熱鬧碑幅,春花似錦、人聲如沸塞绿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽位隶。三九已至,卻和暖如春开皿,著一層夾襖步出監(jiān)牢的瞬間涧黄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工赋荆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留笋妥,地道東北人。 一個月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓窄潭,卻偏偏與公主長得像春宣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子嫉你,可洞房花燭夜當晚...
    茶點故事閱讀 45,926評論 2 361

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