基于環(huán)信2.0實現(xiàn)的聊天Demo

之前有做過和即時通訊相關(guān)的項目,不過貌似已經(jīng)下架了,源碼也找不到了。因為下個項目可能會涉及即時通訊,所以最近幾天把環(huán)信即使通訊的相關(guān)東西又稍微在整理了一些,寫了個小的demo。demo中有登錄、注冊、發(fā)送文字、圖片、聲音消息、群聊、單聊、獲取會話列表、未讀消息通知、自定義聊天界面、自定義鍵盤、增加刪除好好和組等功能,總的來說功能還算齊全,寫的也比較隨意,整個結(jié)構(gòu)沒給整理好,因為最開始想的就是隨便熟悉一下,誰知后來寫了很多功能。這個demo中的聊天界面以及自定義鍵盤都是自己寫的,目前還存在一些不完善的地方,以后有時間了回給補充一下,如發(fā)送消息時聊天界面進度信息。簡單看一下效果圖。


IMG_1554.PNG
IMG_1553.PNG
IMG_1555.PNG

其中的聊天面板和鍵盤都是自己寫的,鍵盤只是寫了個大概,還沒有增加自定義表情,后期會繼續(xù)完善,可能會增加圖文混排功能,自定義表情功能。例外就是因為項目結(jié)構(gòu)沒有搭建的很好,所以最開始在處理收到好友加自己為好友這樣的功能存在一些問題。這里主要是告訴一些新手使用環(huán)信實現(xiàn)這種即時通訊app的一些注意事項,以及搭建聊天界面和自定義鍵盤比較好的思路。實際上搭建一個功能比較完善的聊天界面還是很麻煩的,一般情況下很多人可能就會直接選擇EaseUI。當然,如果想挑戰(zhàn)一下,不防稍微試試。
1.關(guān)閉控制臺登錄信息的打印。

EMError *error = [[EaseMob sharedInstance]registerSDKWithAppKey:@"zhengyawei#zhuanxintestzyw" apnsCertName:@"HuanXinp12" otherConfig:@{kSDKConfigEnableConsoleLogger:@NO}];

2.調(diào)用環(huán)信的程序加載完畢的方法,才能添加代理。之后才能調(diào)用代理方法,否則代理方法不生效。

[[EaseMob sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];

3.發(fā)送文本消息是要注意,去掉\n字符,否則可能聊天界面會無緣無故多出一行。記得之前在這個上面吃過虧,當時怎么也找不出原因。

//**1.接收信息者
        /*==============================*/
        NSString *receiver = self.isGroup? self.group.groupId: self.budddy.username;
        //**2.內(nèi)容對象
        //這里去掉\n
        EMChatText *chatText = [[EMChatText alloc]initWithText:[textView.text substringToIndex:textView.text.length - 1]];
        //**3.創(chuàng)建文本消息體
        EMTextMessageBody *textBody = [[EMTextMessageBody alloc]initWithChatObject:chatText];
        //**4.創(chuàng)建EMMessage對象
        EMMessage *msg = [[EMMessage alloc]initWithReceiver:receiver bodies:@[textBody]];
        /*==============================*/
        msg.messageType = self.isGroup? eMessageTypeGroupChat:eMessageTypeChat;
        //**5.異步發(fā)送消息
        [[EaseMob sharedInstance].chatManager asyncSendMessage:msg progress:self prepare:^(EMMessage *message, EMError *error) {
            NSLog(@"準備發(fā)送文本消息");
        } onQueue:nil completion:^(EMMessage *message, EMError *error) {
            NSLog(@"文本消息發(fā)送成功");
            [self.messageData addObject:message];
            [self scrollBottom];
            //發(fā)送成功后清除數(shù)據(jù)
            textView.text = @"";
        } onQueue:nil];
    };

4.添加過代理后,必須設(shè)置移除代理,所有界面都是如此

-(void)dealloc{
    [[EaseMob sharedInstance].chatManager removeDelegate:self];
}
  1. 下面這個方法主要是聊天管理器, 獲取該對象后, 可以做登錄、聊天、加好友等操作。注意,在獲取會話列表之前要調(diào)用這句代碼,否則可能出現(xiàn)會話列表部分信息顯示不完全。
 [[EaseMob sharedInstance].chatManager loadDataFromDatabase];

6.- (void)didReceiveBuddyRequest:(NSString *)username message:(NSString *)message;類似這種收到好友請求和被被人拉入群的通知,這樣的代理方法要放到tabBarController中記性管理。如果隨便放置,可能收不到這樣的通知,而且控制臺會打印錯誤信息。
7.關(guān)于聊天界面的布局。
在聊天界面布局的時候最好是在控制器的view上,再添加一個sccrollView,然后再將聊天界面的tableView以及自定義鍵盤的工具條放置到這個scrolleView上。這樣更能方便在鍵盤彈出時,管理tableView上消息位置的滑動。思路是這樣的:在鍵盤彈出的時候,讓整個scrollView都忘上升。這樣工具條和tableView都會同步上升。另外還要充分利用tableView的contentInset屬性,自我感覺這個屬性如果用好了,在實際項目中可以處理很多問題。在聊天界面中,這個屬性的主要解決的問題是:防止聊天記錄中內(nèi)容過少,鍵盤彈出時聊天記錄看不見。只需簡單一行代碼就能解決這個問題。代碼如下:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrameNotification:) name:UIKeyboardWillChangeFrameNotification object:nil];


- (void)keyboardWillChangeFrameNotification:(NSNotification *)noti
{
    CGRect keyboardF = [noti.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    if (keyboardF.origin.y < kWeChatScreenHeight) {
        self.contentView.top = - keyboardF.size.height;
        //設(shè)置tableView的內(nèi)邊距,防止聊天記錄中內(nèi)容過少,鍵盤彈出時聊天記錄看不見
        self.chatTableView.contentInset = UIEdgeInsetsMake(keyboardF.size.height, 0, 0, 0);
        //鍵盤彈出時,tableView也要滾到最底部
        //這里要做這樣的判斷,防止沒有聊天記錄的時候,出現(xiàn)數(shù)組越界
        if (self.messageData.count != 0 ) {
            [self.chatTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.messageData.count - 1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        }
        
    }else{
        self.contentView.top = 0;
        self.chatTableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
    }
}

8.聊天界面的文字消息、圖片消息以及聲音消息,建議都使用UIButton這個空間進行處理。因為這些聲音消息和圖片消息,都涉及到點擊事件。可能后期如果想擴充地理位置,視頻消息也會涉及點擊事件,如果都是添加點擊手勢,感覺會過于麻煩。因為UIBUtton本身就帶有image和titleLabel屬性,所以圖片和文字消息都可以在上面進行展示。調(diào)節(jié)UIButton上的圖片和文字位置主要可以通過下面這兩行代碼:

//具體位置根據(jù)實際需求進行調(diào)節(jié)
self.chatBtn.titleEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
        self.chatBtn.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);

9.關(guān)于自定義鍵盤如果更方便的在鍵盤和自定義視圖之間進行切換。這里主要提供兩種思路。
第一種方法是,將聊天面板添加到[UIApplication sharedApplication].keyWindow上,在切換鍵盤的時候控制聊天面板的y值。不過這種方法使用起來設(shè)計到的邏輯判斷會比較多,不是很方便,更推薦使用第二種方法。
第二種發(fā)放實現(xiàn)思路,充分利用UITextView或UITextField的inputView屬性,首先要知道當_textView.inputView = nil的時候,則顯示輸入視圖inputView就是系統(tǒng)的鍵盤;如果是自己_textView.inputView = customeView,這是顯示的就是自己自定義的視圖。通過在nil和customeView這兩個值之間的切換,就可以實現(xiàn)在鍵盤和自定義視圖之間的切換,根本沒有涉及太多的邏輯。注意:如果想封裝一個屬于自己的自定義鍵盤,這個inputView屬性起到的作用很大。

#pragma mark - 表情和鍵盤面板切換
- (void)keyBoardButtonClick:(UIButton *)btn{
    if (btn.isSelected == NO) {//切換到表情
         _textView.inputView = self.faceBoard;
        btn.selected = YES;
    }else{//切換到系統(tǒng)鍵盤
        UIView *view = [[UIView alloc]init];
        view.backgroundColor = [UIColor cyanColor];
        view.frame = CGRectMake(0, 0, self.view.frame.size.width, 100);
        _textView.inputView = nil;
         btn.selected = NO;
    }

    if (_textView.isFirstResponder == YES) {
        [_textView resignFirstResponder];
        [_textView becomeFirstResponder];
    }else{
        [_textView becomeFirstResponder];
    }
}

Demo下載地址:https://pan.baidu.com/s/1nuF1puL

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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