基于环信2.0实现的聊天Demo

之前有做过和即时通讯相关的项目,不过貌似已经下架了,源码也找不到了。因为下个项目可能会涉及即时通讯,所以最近几天把环信即使通讯的相关东西又稍微在整理了一些,写了个小的demo。demo中有登录、注册、发送文字、图片、声音消息、群聊、单聊、获取会话列表、未读消息通知、自定义聊天界面、自定义键盘、增加删除好好和组等功能,总的来说功能还算齐全,写的也比较随意,整个结构没给整理好,因为最开始想的就是随便熟悉一下,谁知后来写了很多功能。这个demo中的聊天界面以及自定义键盘都是自己写的,目前还存在一些不完善的地方,以后有时间了回给补充一下,如发送消息时聊天界面进度信息。简单看一下效果图。


IMG_1554.PNG
IMG_1553.PNG
IMG_1555.PNG

其中的聊天面板和键盘都是自己写的,键盘只是写了个大概,还没有增加自定义表情,后期会继续完善,可能会增加图文混排功能,自定义表情功能。例外就是因为项目结构没有搭建的很好,所以最开始在处理收到好友加自己为好友这样的功能存在一些问题。这里主要是告诉一些新手使用环信实现这种即时通讯app的一些注意事项,以及搭建聊天界面和自定义键盘比较好的思路。实际上搭建一个功能比较完善的聊天界面还是很麻烦的,一般情况下很多人可能就会直接选择EaseUI。当然,如果想挑战一下,不防稍微试试。
1.关闭控制台登录信息的打印。

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

2.调用环信的程序加载完毕的方法,才能添加代理。之后才能调用代理方法,否则代理方法不生效。

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

3.发送文本消息是要注意,去掉\n字符,否则可能聊天界面会无缘无故多出一行。记得之前在这个上面吃过亏,当时怎么也找不出原因。

//**1.接收信息者
        /*==============================*/
        NSString *receiver = self.isGroup? self.group.groupId: self.budddy.username;
        //**2.内容对象
        //这里去掉\n
        EMChatText *chatText = [[EMChatText alloc]initWithText:[textView.text substringToIndex:textView.text.length - 1]];
        //**3.创建文本消息体
        EMTextMessageBody *textBody = [[EMTextMessageBody alloc]initWithChatObject:chatText];
        //**4.创建EMMessage对象
        EMMessage *msg = [[EMMessage alloc]initWithReceiver:receiver bodies:@[textBody]];
        /*==============================*/
        msg.messageType = self.isGroup? eMessageTypeGroupChat:eMessageTypeChat;
        //**5.异步发送消息
        [[EaseMob sharedInstance].chatManager asyncSendMessage:msg progress:self prepare:^(EMMessage *message, EMError *error) {
            NSLog(@"准备发送文本消息");
        } onQueue:nil completion:^(EMMessage *message, EMError *error) {
            NSLog(@"文本消息发送成功");
            [self.messageData addObject:message];
            [self scrollBottom];
            //发送成功后清除数据
            textView.text = @"";
        } onQueue:nil];
    };

4.添加过代理后,必须设置移除代理,所有界面都是如此

-(void)dealloc{
    [[EaseMob sharedInstance].chatManager removeDelegate:self];
}
  1. 下面这个方法主要是聊天管理器, 获取该对象后, 可以做登录、聊天、加好友等操作。注意,在获取会话列表之前要调用这句代码,否则可能出现会话列表部分信息显示不完全。
 [[EaseMob sharedInstance].chatManager loadDataFromDatabase];

6.- (void)didReceiveBuddyRequest:(NSString *)username message:(NSString *)message;类似这种收到好友请求和被被人拉入群的通知,这样的代理方法要放到tabBarController中记性管理。如果随便放置,可能收不到这样的通知,而且控制台会打印错误信息。
7.关于聊天界面的布局。
在聊天界面布局的时候最好是在控制器的view上,再添加一个sccrollView,然后再将聊天界面的tableView以及自定义键盘的工具条放置到这个scrolleView上。这样更能方便在键盘弹出时,管理tableView上消息位置的滑动。思路是这样的:在键盘弹出的时候,让整个scrollView都忘上升。这样工具条和tableView都会同步上升。另外还要充分利用tableView的contentInset属性,自我感觉这个属性如果用好了,在实际项目中可以处理很多问题。在聊天界面中,这个属性的主要解决的问题是:防止聊天记录中内容过少,键盘弹出时聊天记录看不见。只需简单一行代码就能解决这个问题。代码如下:

 [[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;
        //设置tableView的内边距,防止聊天记录中内容过少,键盘弹出时聊天记录看不见
        self.chatTableView.contentInset = UIEdgeInsetsMake(keyboardF.size.height, 0, 0, 0);
        //键盘弹出时,tableView也要滚到最底部
        //这里要做这样的判断,防止没有聊天记录的时候,出现数组越界
        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属性,所以图片和文字消息都可以在上面进行展示。调节UIButton上的图片和文字位置主要可以通过下面这两行代码:

//具体位置根据实际需求进行调节
self.chatBtn.titleEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
        self.chatBtn.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);

9.关于自定义键盘如果更方便的在键盘和自定义视图之间进行切换。这里主要提供两种思路。
第一种方法是,将聊天面板添加到[UIApplication sharedApplication].keyWindow上,在切换键盘的时候控制聊天面板的y值。不过这种方法使用起来设计到的逻辑判断会比较多,不是很方便,更推荐使用第二种方法。
第二种发放实现思路,充分利用UITextView或UITextField的inputView属性,首先要知道当_textView.inputView = nil的时候,则显示输入视图inputView就是系统的键盘;如果是自己_textView.inputView = customeView,这是显示的就是自己自定义的视图。通过在nil和customeView这两个值之间的切换,就可以实现在键盘和自定义视图之间的切换,根本没有涉及太多的逻辑。注意:如果想封装一个属于自己的自定义键盘,这个inputView属性起到的作用很大。

#pragma mark - 表情和键盘面板切换
- (void)keyBoardButtonClick:(UIButton *)btn{
    if (btn.isSelected == NO) {//切换到表情
         _textView.inputView = self.faceBoard;
        btn.selected = YES;
    }else{//切换到系统键盘
        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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容