集成环信的即时通讯

上官网注册账号

首先来到环信的官网,然后登陆.没有账号先注册一个.

进去之后创建应用,如图

创建应用界面

点击确定后,来到这个界面,只需要记住应用标示(APPKey)就行,待会儿会在代码里用到它.

屏幕快照 2016-01-04 下午7.18.38.png

然后用cocoapods导入环信SDK,大家可以通过这篇博客来安装cocoapods.

创建项目

打开终端,输入cd,然后将项目入进去回车,就跳到项目地址,输入命令:pod

init,然后会生成一个Podfile,双击这个文件,将里面的东西全删了,然后输入:pod 'EaseMobSDK',然后在终端输入命令:pod

install(如果不行可以试试:pod install --verbose

--no-repo-update).接下来就等着SDK下载安装到项目里了,大概几分钟后就好了.这时候需要双击.xcworkspace的那个文件进去.SDK集成就完成了(不知道为什么官方文档里面写的集成特别复杂,需要导入各种框架,修改很多东西,其实只要终端一条指令就OK了).

AppDelegate

大家还记得刚才的APPKey吧,在AppDelegate里面需要注册使用.

#import"AppDelegate.h"#import"ViewController.h"#import@interfaceAppDelegate()@end@implementationAppDelegate- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {    _window = [[UIWindowalloc]initWithFrame:[UIScreenmainScreen].bounds];    _window.backgroundColor = [UIColorwhiteColor];    [_window makeKeyAndVisible];UINavigationController*nav = [[UINavigationControlleralloc]initWithRootViewController:[[ViewController alloc]init]];    _window.rootViewController = nav;//注册环信[[EaseMob sharedInstance]registerSDKWithAppKey:@"xmh123#cdxmh"apnsCertName:@""];returnYES;}- (void)applicationWillResignActive:(UIApplication*)application {// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.}- (void)applicationDidEnterBackground:(UIApplication*)application {    [[EaseMob sharedInstance] applicationDidEnterBackground:application];}- (void)applicationWillEnterForeground:(UIApplication*)application {    [[EaseMob sharedInstance] applicationWillEnterForeground:application];}- (void)applicationDidBecomeActive:(UIApplication*)application {// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.}- (void)applicationWillTerminate:(UIApplication*)application {    [[EaseMob sharedInstance]applicationWillTerminate:application];}@end

登陆界面

登陆界面

看看这部分的代码吧.

#import"ViewController.h"#import"RegisterViewController.h"#import"FriendListViewController.h"#import@interfaceViewController()@property(nonatomic,strong)UITextField*userNameTextField;//用户名@property(nonatomic,strong)UITextField*passwordTextField;//密码@property(nonatomic,strong)UIButton*loginButton;//登陆按钮@property(nonatomic,strong)UIButton*registerButton;//注册按钮@end@implementationViewController- (void)viewDidLoad {    [superviewDidLoad];self.view.backgroundColor = [UIColorwhiteColor];self.navigationController.navigationBar.translucent =NO;self.title =@"登陆界面";UILabel*usernameLabel = [[UILabelalloc]initWithFrame:CGRectMake(20,100,80,50)];    usernameLabel.text =@"用户名";    usernameLabel.font = [UIFontsystemFontOfSize:25];    [self.view addSubview:usernameLabel];    _userNameTextField = [[UITextFieldalloc]initWithFrame:CGRectMake(usernameLabel.frame.origin.x + usernameLabel.frame.size.width +10, usernameLabel.frame.origin.y,250,50)];    _userNameTextField.borderStyle =3;    _userNameTextField.placeholder =@"请输入用户名";    [self.view addSubview:_userNameTextField];UILabel*passwordLabel = [[UILabelalloc]initWithFrame:CGRectMake(usernameLabel.frame.origin.x, usernameLabel.frame.origin.y + usernameLabel.frame.size.height +10, usernameLabel.frame.size.width, usernameLabel.frame.size.height)];    passwordLabel.text =@"密码";    passwordLabel.font = [UIFontsystemFontOfSize:25];    [self.view addSubview:passwordLabel];    _passwordTextField = [[UITextFieldalloc]initWithFrame:CGRectMake(_userNameTextField.frame.origin.x, passwordLabel.frame.origin.y, _userNameTextField.frame.size.width, _userNameTextField.frame.size.height)];    _passwordTextField.placeholder =@"请输入密码";    _passwordTextField.borderStyle =3;    [self.view addSubview:_passwordTextField];    _loginButton = [UIButtonbuttonWithType:UIButtonTypeSystem];    _loginButton.frame =CGRectMake(170,300,50,50);    _loginButton.titleLabel.font = [UIFontsystemFontOfSize:25];    [_loginButton setTitle:@"登陆"forState:UIControlStateNormal];    [_loginButton addTarget:selfaction:@selector(didClickLoginButton) forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:_loginButton];    _registerButton = [UIButtonbuttonWithType:UIButtonTypeSystem];    _registerButton.frame =CGRectMake(170,410,50,50);    _registerButton.titleLabel.font = [UIFontsystemFontOfSize:25];    [_registerButton setTitle:@"注册"forState:UIControlStateNormal];    [_registerButton addTarget:selfaction:@selector(jumpToRegister) forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:_registerButton];}-(void)didClickLoginButton{    [[EaseMob sharedInstance].chatManager asyncLoginWithUsername:_userNameTextField.text password:_passwordTextField.text completion:^(NSDictionary*loginInfo, EMError *error) {if(!error) {//如果验证用户名和密码没有问题就跳转到好友列表界面[self.navigationController pushViewController:[[FriendListViewController alloc]init] animated:YES];        }else{// 显示错误信息的警告NSLog(@"%@",error);        }    } onQueue:dispatch_get_main_queue()];}-(void)jumpToRegister{//跳转到注册界面RegisterViewController *registerVC = [[RegisterViewController alloc]init];    [self.navigationController presentViewController:registerVC animated:YEScompletion:nil];}- (void)didReceiveMemoryWarning {    [superdidReceiveMemoryWarning];// Dispose of any resources that can be recreated.}@end

这个界面很简单,大部分都是界面搭建,当点击登陆时会调用

[[EaseMob sharedInstance].chatManagerasyncLoginWithUsername:_userNameTextField.textpassword:_passwordTextField.textcompletion:^(NSDictionary *loginInfo, EMError *error)

这个方法有2个参数,一个用户名,一个是密码,很容易猜到这就是验证你的用户名和密码是否正确,如果正确就跳转到好友列表界面,如果不对就会在控制台打印相应的错误.

点击注册就跳转到注册界面.

注册界面

注册界面

由于第一次登陆时没有账号,所以先得注册.先看看代码:

#import"RegisterViewController.h"#import@interfaceRegisterViewController()@property(nonatomic,strong)UITextField*userNameTextField;//用户名@property(nonatomic,strong)UITextField*passwordTextField;//密码@property(nonatomic,strong)UIButton*registerButton;//注册按钮@end@implementationRegisterViewController- (void)viewDidLoad {    [superviewDidLoad];self.view.backgroundColor = [UIColorwhiteColor];self.navigationController.navigationBar.translucent =NO;self.title =@"登陆界面";UILabel*usernameLabel = [[UILabelalloc]initWithFrame:CGRectMake(20,100,80,50)];    usernameLabel.text =@"用户名";    usernameLabel.font = [UIFontsystemFontOfSize:25];    [self.view addSubview:usernameLabel];    _userNameTextField = [[UITextFieldalloc]initWithFrame:CGRectMake(usernameLabel.frame.origin.x + usernameLabel.frame.size.width +10, usernameLabel.frame.origin.y,250,50)];    _userNameTextField.borderStyle =3;    _userNameTextField.placeholder =@"请输入用户名";    [self.view addSubview:_userNameTextField];UILabel*passwordLabel = [[UILabelalloc]initWithFrame:CGRectMake(usernameLabel.frame.origin.x, usernameLabel.frame.origin.y + usernameLabel.frame.size.height +10, usernameLabel.frame.size.width, usernameLabel.frame.size.height)];    passwordLabel.text =@"密码";    passwordLabel.font = [UIFontsystemFontOfSize:25];    [self.view addSubview:passwordLabel];    _passwordTextField = [[UITextFieldalloc]initWithFrame:CGRectMake(_userNameTextField.frame.origin.x, passwordLabel.frame.origin.y, _userNameTextField.frame.size.width, _userNameTextField.frame.size.height)];    _passwordTextField.placeholder =@"请输入密码";    _passwordTextField.borderStyle =3;    [self.view addSubview:_passwordTextField];    _registerButton = [UIButtonbuttonWithType:UIButtonTypeSystem];    _registerButton.frame =CGRectMake(170,330,50,50);    _registerButton.titleLabel.font = [UIFontsystemFontOfSize:25];    [_registerButton setTitle:@"注册"forState:UIControlStateNormal];    [_registerButton addTarget:selfaction:@selector(didClickedRegisterButton:) forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:_registerButton];UIButton*backButton = [UIButtonbuttonWithType:UIButtonTypeSystem];    backButton.frame =CGRectMake(170,280,50,50);    backButton.titleLabel.font = [UIFontsystemFontOfSize:25];    [backButton setTitle:@"返回"forState:UIControlStateNormal];    [backButton addTarget:selfaction:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:backButton];}-(void)backAction{    [selfdismissViewControllerAnimated:YEScompletion:nil];}-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{//点击屏幕时让键盘回收[_passwordTextField resignFirstResponder];    [_userNameTextField resignFirstResponder];}-(void)didClickedRegisterButton:(id)sender{//  登陆和注册有3种方法: 1. 同步方法 2. 通过delegate回调的异步方法。3.block异步方法//其中官方推荐使用block异步方法,所以我这里就用block异步方法//开始注册[[EaseMob sharedInstance].chatManager asyncRegisterNewAccount:_userNameTextField.text password:_passwordTextField.text withCompletion:^(NSString*username,NSString*password, EMError *error) {if(!error) {NSLog(@"注册成功");            [selfdismissViewControllerAnimated:YEScompletion:nil];        }else{NSLog(@"%@",error);        }    } onQueue:dispatch_get_main_queue()];}- (void)didReceiveMemoryWarning {    [superdidReceiveMemoryWarning];// Dispose of any resources that can be recreated.}/*

#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

}

@end

这个界面也特别简单,除了界面搭建,就只有这个方法:

[[EaseMob sharedInstance].chatManagerasyncRegisterNewAccount:_userNameTextField.textpassword:_passwordTextField.textwithCompletion:^(NSString *username, NSString *password, EMError *error)

一共两个参数,就是用户名和密码,然后判断用户名和密码是否可用,如果可用就返回到登陆界面.

好友列表界面

好友列表界面

这里我只加了一个好友叫xiaomei.

好友界面是怎么样的呢,大家先看看代码:

#import"FriendListViewController.h"#import"AddFriendViewController.h"#import"ChatViewController.h"#import@interfaceFriendListViewController()@property(nonatomic,strong)NSMutableArray*listArray;@property(nonatomic,strong)UITableView*tableView;@end@implementationFriendListViewController-(void)viewWillAppear:(BOOL)animated{    [superviewWillAppear:animated];    }-(void)loadView{    [superloadView];self.view.backgroundColor = [UIColorwhiteColor];//左侧注销按钮self.navigationItem.leftBarButtonItem = [[UIBarButtonItemalloc]initWithTitle:@"注销"style:UIBarButtonItemStylePlaintarget:selfaction:@selector(didClickedCancelButton)];self.title =@"好友";    [[EaseMob sharedInstance].chatManager asyncFetchBuddyListWithCompletion:^(NSArray*buddyList, EMError *error) {if(!error) {NSLog(@"获取成功 -- %@", buddyList);            [_listArray removeAllObjects];            [_listArray addObjectsFromArray:buddyList];            [_tableView reloadData];        }    } onQueue:dispatch_get_main_queue()];}- (void)viewDidLoad {    [superviewDidLoad];    _listArray = [NSMutableArraynew];self.navigationItem.rightBarButtonItem = [[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAddtarget:selfaction:@selector(addbuttonAction)];    _tableView = [[UITableViewalloc]initWithFrame:self.view.frame];    _tableView.delegate =self;    _tableView.dataSource =self;    _tableView.tableFooterView = [[UIViewalloc]init];    [self.view addSubview:_tableView];//签协议[ [EaseMob sharedInstance].chatManager addDelegate:selfdelegateQueue:dispatch_get_main_queue()];}-(void)didClickedCancelButton{//注销用户[[EaseMob sharedInstance].chatManager asyncLogoffWithUnbindDeviceToken:YES];    [self.navigationController popViewControllerAnimated:YES];}-(void)addbuttonAction{    [self.navigationController pushViewController:[[AddFriendViewController alloc]init] animated:YES];}# pragma mark - Table View Data Source- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {return_listArray.count;}-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath{return50;}- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {staticNSString*identifier =@"cell";UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:identifier];if(!cell) {        cell = [[UITableViewCellalloc]initWithStyle:UITableViewCellStyleValue1reuseIdentifier:identifier];    }    EMBuddy * buddy = _listArray[indexPath.row];    cell.textLabel.text = buddy.username;returncell;}- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {    ChatViewController * chatVC = [[ChatViewController alloc]init];    EMBuddy * buddy = _listArray[indexPath.row];    chatVC.name = buddy.username;    [self.navigationController pushViewController:chatVC animated:YES];}-(void)didReceiveBuddyRequest:(NSString*)username message:(NSString*)message{UIAlertController* alertController = [UIAlertControlleralertControllerWithTitle:[NSStringstringWithFormat:@"收到来自%@的请求", username] message:message preferredStyle:(UIAlertControllerStyleAlert)];UIAlertAction* acceptAction = [UIAlertActionactionWithTitle:@"好"style:(UIAlertActionStyleDefault) handler:^(UIAlertAction*  action) {        EMError * error;// 同意好友请求的方法if([[EaseMob sharedInstance].chatManager acceptBuddyRequest:username error:&error] && !error) {NSLog(@"发送同意成功");            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{                [[EaseMob sharedInstance].chatManager asyncFetchBuddyListWithCompletion:^(NSArray*buddyList, EMError *error) {if(!error) {NSLog(@"获取成功 -- %@", buddyList);                        [_listArray removeAllObjects];                        [_listArray addObjectsFromArray:buddyList];                        [_tableView reloadData];                    }                } onQueue:dispatch_get_main_queue()];            });        }    }];UIAlertAction* rejectAction = [UIAlertActionactionWithTitle:@"滚"style:(UIAlertActionStyleCancel) handler:^(UIAlertAction* _Nonnull action) {        EMError * error;// 拒绝好友请求的方法if([[EaseMob sharedInstance].chatManager rejectBuddyRequest:username reason:@"滚, 快滚!"error:&error] && !error) {NSLog(@"发送拒绝成功");        }    }];    [alertController addAction:acceptAction];    [alertController addAction:rejectAction];    [selfshowDetailViewController:alertController sender:nil];}- (void)didReceiveMemoryWarning {    [superdidReceiveMemoryWarning];// Dispose of any resources that can be recreated.}

首先,使用下面这个方法获取到所有的好友,然后将好友放入你的数组,这样好友的信息都在数组里了

[[EaseMob sharedInstance].chatManager asyncFetchBuddyListWithCompletion:^(NSArray*buddyList, EMError *error) {        if (!error) {            NSLog(@"获取成功 -- %@", buddyList);[_listArray removeAllObjects];[_listArray addObjectsFromArray:buddyList];[_tableView reloadData];}    } onQueue:dispatch_get_main_queue()];

tableView没行的信息通过下面这个方法,刚才已经把所有好友的信息方法数组里了,那么就可以通过EMBuddy * buddy =

_listArray[indexPath.row]这个方法获取单个好友信息,用  cell.textLabel.text =

buddy.username给每个cell的text赋值.

- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {staticNSString*identifier =@"cell";UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:identifier];if(!cell) {        cell = [[UITableViewCellalloc]initWithStyle:UITableViewCellStyleValue1reuseIdentifier:identifier];    }    EMBuddy * buddy = _listArray[indexPath.row];    cell.textLabel.text = buddy.username;returncell;}

当别人想加你为好友时,会调用这个方法.先弹出一个提示框,然后根据你的选择而去接受或者拒绝.如果接受,就重新导入一遍数据,然后刷新tableView.如果拒绝就调用拒绝的方法.这并不难理解吧.

-(void)didReceiveBuddyRequest:(NSString *)usernamemessage:(NSString *)message{ UIAlertController * alertController = [UIAlertControlleralertControllerWithTitle:[NSStringstringWithFormat:@"收到来自%@的请求", username]message:messagepreferredStyle:(UIAlertControllerStyleAlert)];    UIAlertAction * acceptAction = [UIAlertActionactionWithTitle:@"好"style:(UIAlertActionStyleDefault)handler:^(UIAlertAction *  action) {        EMError * error;// 同意好友请求的方法if([[EaseMob sharedInstance].chatManageracceptBuddyRequest:usernameerror:&error] && !error) {            NSLog(@"发送同意成功");                [[EaseMob sharedInstance].chatManagerasyncFetchBuddyListWithCompletion:^(NSArray *buddyList, EMError *error) {if(!error) {                        NSLog(@"获取成功 -- %@", buddyList);                        [_listArray removeAllObjects];                        [_listArrayaddObjectsFromArray:buddyList];                        [_tableView reloadData];                    }                }onQueue:dispatch_get_main_queue()];        }    }];    UIAlertAction * rejectAction = [UIAlertActionactionWithTitle:@"滚"style:(UIAlertActionStyleCancel)handler:^(UIAlertAction * _Nonnull action) {        EMError * error;// 拒绝好友请求的方法if([[EaseMob sharedInstance].chatManagerrejectBuddyRequest:usernamereason:@"滚, 快滚!"error:&error] && !error) {            NSLog(@"发送拒绝成功");        }    }];    [alertControlleraddAction:acceptAction];    [alertControlleraddAction:rejectAction];    [selfshowDetailViewController:alertControllersender:nil];

聊天界面

聊天界面

在看聊天界面之前先需要自定义一个聊天输入框,就是下面那个带一个textfield和button的.

DialogBoxView.m

#import"DialogBoxView.h"@interfaceDialogBoxView()@property(nonatomic,strong)UITextField* draftTextField;@property(nonatomic,strong)UIButton* sendButton;@end@implementationDialogBoxView- (instancetype)initWithFrame:(CGRect)frame{self= [superinitWithFrame:frame];if(self) {        [selfinitView];    }returnself;}- (void)initView{    [selfsetBackgroundColor:[UIColorcolorWithWhite:0.9alpha:1]];    _draftTextField = [[UITextFieldalloc] initWithFrame:CGRectMake(5,5,self.frame.size.width -100,self.frame.size.height -10)];    [_draftTextField setBorderStyle:(UITextBorderStyleRoundedRect)];    [_draftTextField setPlaceholder:@"说点什么呢"];    [_draftTextField setFont:[UIFontsystemFontOfSize:13]];    [selfaddSubview:_draftTextField];    _sendButton = [UIButtonbuttonWithType:(UIButtonTypeCustom)];    [_sendButton setFrame:CGRectMake(self.frame.size.width -90,5,85,self.frame.size.height -10)];    [_sendButton setBackgroundColor:[UIColorcolorWithRed:1green:0blue:128/255.0alpha:1]];    [_sendButton setTitle:@"发送"forState:(UIControlStateNormal)];    [_sendButton setTitleColor:[UIColorwhiteColor] forState:UIControlStateNormal];    [_sendButton.titleLabel setFont:[UIFontboldSystemFontOfSize:15]];    [_sendButton.layer setMasksToBounds:YES];    [_sendButton.layer setCornerRadius:4];    [_sendButton addTarget:selfaction:@selector(didSendButtonClicked:) forControlEvents:(UIControlEventTouchUpInside)];    [selfaddSubview:_sendButton];}- (void)didSendButtonClicked:(UIButton*)sender {if(self.buttonClicked) {self.buttonClicked(_draftTextField.text);    }    _draftTextField.text =@"";}- (NSString*)draftText {return_draftTextField.text;}/*

// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect {

// Drawing code

}

*/@end

这个简单的自定义view没什么好说的,关键是他的.h文件

DialogBoxView.h

#importtypedefvoid(^ButtonClicked)(NSString* draftText);@interfaceDialogBoxView:UIView@property(nonatomic,copy) ButtonClicked buttonClicked;@end

这里用到一个block,当点击按钮时会调用这个block.

接下看看聊天界面的代码吧.

#import"ChatViewController.h"#import"DialogBoxView.h"#import@interfaceChatViewController()@property(nonatomic,strong)UITableView*tableView;@property(nonatomic,strong)EMConversation *conversation;@property(nonatomic,strong)DialogBoxView *dialogBoxView;@end@implementationChatViewController-(void)loadView{    [superloadView];self.title = _name;self.navigationController.navigationBar.translucent =NO;    _tableView = [[UITableViewalloc]initWithFrame:CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height -50)];    _tableView.delegate =self;    _tableView.dataSource =self;    _tableView.tableFooterView = [[UIViewalloc]init];    [self.view addSubview:_tableView];}- (void)viewDidLoad {    [superviewDidLoad];    [_tableView setAllowsSelection:NO];    [selfregisterForKeyboardNotifications];    _dialogBoxView = [[DialogBoxView alloc]initWithFrame:CGRectMake(0,self.view.frame.size.height -114,self.view.frame.size.width,50)];    __weaktypeof(self) weakSelf =self;    _dialogBoxView.buttonClicked = ^(NSString* draftText){        [weakSelf sendMessageWithDraftText:draftText];    };    [self.view addSubview:_dialogBoxView];    [[EaseMob sharedInstance].chatManager addDelegate:selfdelegateQueue:dispatch_get_main_queue()];    [selfreloadChatRecords];}- (void)viewWillDisappear:(BOOL)animated {    [superviewWillDisappear:animated];// 移除通知中心[selfremoveForKeyboardNotifications];// 移除代理[[EaseMob sharedInstance].chatManager removeDelegate:self];}# pragma mark - Send Message/**

*  使用草稿发送一条信息

*

*  @param draftText 草稿

*/- (void)sendMessageWithDraftText:(NSString*)draftText {    EMChatText * chatText = [[EMChatText alloc] initWithText:draftText];    EMTextMessageBody * body = [[EMTextMessageBody alloc] initWithChatObject:chatText];// 生成messageEMMessage * message = [[EMMessage alloc] initWithReceiver:self.name bodies:@[body]];    message.messageType = eMessageTypeChat;// 设置为单聊消息[[EaseMob sharedInstance].chatManager asyncSendMessage:message progress:nilprepare:^(EMMessage *message, EMError *error) {// 准备发送} onQueue:dispatch_get_main_queue() completion:^(EMMessage *message, EMError *error) {        [selfreloadChatRecords];// 发送完成} onQueue:dispatch_get_main_queue()];}# pragma mark - Receive Message/**

*  当收到了一条消息时

*

*  @param message 消息构造体

*/- (void)didReceiveMessage:(EMMessage *)message {    [selfreloadChatRecords];}# pragma mark - Reload Chat Records/**

*  重新加载TableView上面显示的聊天信息, 并移动到最后一行

*/- (void)reloadChatRecords {    _conversation = [[EaseMob sharedInstance].chatManager conversationForChatter:self.name conversationType:eConversationTypeChat];    [_tableView reloadData];if([_conversation loadAllMessages].count >0) {        [_tableView scrollToRowAtIndexPath:[NSIndexPathindexPathForRow:[_conversation loadAllMessages].count -1inSection:0] atScrollPosition:(UITableViewScrollPositionBottom) animated:YES];    }}# pragma mark - Keyboard Method/**

*  注册通知中心

*/- (void)registerForKeyboardNotifications{// 使用NSNotificationCenter 注册观察当键盘要出现时[[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(didKeyboardWillShow:) name:UIKeyboardWillShowNotificationobject:nil];// 使用NSNotificationCenter 注册观察当键盘要隐藏时[[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(didKeyboardWillHide:) name:UIKeyboardWillHideNotificationobject:nil];}/**

*  移除通知中心

*/- (void)removeForKeyboardNotifications {    [[NSNotificationCenterdefaultCenter] removeObserver:self];}/**

*  键盘将要弹出

*

*  @param notification 通知

*/- (void)didKeyboardWillShow:(NSNotification*)notification {NSDictionary* info = [notification userInfo];CGSizekeyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey]CGRectValue].size;NSLog(@"%f", keyboardSize.height);//输入框位置动画加载[selfbegainMoveUpAnimation:keyboardSize.height];}/**

*  键盘将要隐藏

*

*  @param notification 通知

*/- (void)didKeyboardWillHide:(NSNotification*)notification {    [selfbegainMoveUpAnimation:0];}/**

*  开始执行键盘改变后对应视图的变化

*

*  @param height 键盘的高度

*/- (void)begainMoveUpAnimation:(CGFloat)height {    [UIViewanimateWithDuration:0.3animations:^{        [_dialogBoxView setFrame:CGRectMake(0,self.view.frame.size.height - (height +40), _dialogBoxView.frame.size.width, _dialogBoxView.frame.size.height)];    }];    [_tableView layoutIfNeeded];if([_conversation loadAllMessages].count >1) {        [_tableView scrollToRowAtIndexPath:[NSIndexPathindexPathForRow:_conversation.loadAllMessages.count -1inSection:0] atScrollPosition:(UITableViewScrollPositionMiddle) animated:YES];    }}# pragma mark - Table View Data Source- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {return_conversation.loadAllMessages.count;}- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {staticNSString*identifier =@"cell";UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:identifier];if(!cell) {        cell = [[UITableViewCellalloc]initWithStyle:UITableViewCellStyleValue1reuseIdentifier:identifier];    }    EMMessage * message = _conversation.loadAllMessages[indexPath.row];    EMTextMessageBody * body = [message.messageBodies lastObject];//判断发送的人是否是当前聊天的人,左边是对面发过来的,右边是自己发过去的if([message.to isEqualToString:self.name]) {        cell.detailTextLabel.text = body.text;        cell.detailTextLabel.textColor = [UIColorredColor];        cell.textLabel.text =@"";        cell.textLabel.textColor = [UIColorblueColor];    }else{        cell.detailTextLabel.text =@"";        cell.textLabel.text = body.text;        cell.detailTextLabel.textColor = [UIColorredColor];        cell.textLabel.textColor = [UIColorblueColor];    }returncell;}- (void)didReceiveMemoryWarning {    [superdidReceiveMemoryWarning];// Dispose of any resources that can be recreated.}@end

这里面也没什么难点,也有注释,相信大家能懂.

最后看看最后的成果图吧.

成品图

好了,今天就到这里,祝大家天天开心


如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

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

推荐阅读更多精彩内容

  • 聊天控制器(ChatViewController)界面搭建 14.聊天界面-工具条排版 1)搭建界面 添加聊天控制...
    夜空已沉寂阅读 2,922评论 0 4
  • 现在即时通讯比较火,很多公司会用到即时通讯,所以今天给大家讲讲即时通讯,因为没有服务器,所以使用了环信的SDK写了...
    徐老茂阅读 14,673评论 32 107
  • 前言 最近忙完项目比较闲,想写一篇博客来分享一些自学iOS的心得体会,希望对迷茫的你有所帮助。博主非科班出身,一些...
    GitHubPorter阅读 1,396评论 9 5
  • 我喜欢信仰这个词 我喜欢以撒,约瑟,和英雄的摩西 因为纯净,因为信仰 因为苦难中的刚强 如果人心飘扬淡雅,没有信仰...
    带走我的xz阅读 301评论 0 3