标签:
当然在集成环信之前需要一些准备操作:
1、首先注册环信开发者账号,直接进入环信官网注册即可:http://www.easemob.com
2、按照文档一步一步将需要的文件全部拖入工程中:http://docs.easemob.com/start/start
以下是我集成的文件:使用
EaseUI集成:http://docs.easemob.com/start/300iosclientintegration/140easeuiuseguide
libEaseMobClientSDK.a包
ChatDemo-UI3.0中的ChatView中的聊天控制器
我主要使用EaseMob中这个EaseSDKHelper单例类来注册、登录、获取最新消息、推送等
在App启动程序时:
进入EaseSDKHelper单例类中,添加一些自定义的方法
#pragma mark - init easemob 注册环信
- (void)easemobApplication:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
appkey:(NSString *)appkey
apnsCertName:(NSString *)apnsCertName
otherConfig:(NSDictionary *)otherConfig
{
//注册登录状态监听
// [[NSNotificationCenter defaultCenter] addObserver:self
// selector:@selector(loginStateChange:)
// name:KNOTIFICATION_LOGINCHANGE
// object:nil];
//注册AppDelegate默认回调监听
[self _setupAppDelegateNotifications];
//注册apns
[self _registerRemoteNotification];
//注册easemob sdk
[[EaseMob sharedInstance] registerSDKWithAppKey:appkey
apnsCertName:apnsCertName
otherConfig:otherConfig];
// 注册环信监听
[self registerEaseMobLiteNotification];
//启动easemob sdk
[[EaseMob sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
[[EaseMob sharedInstance].chatManager setIsAutoFetchBuddyList:YES];
}
#pragma mark - EMChatManagerLoginDelegate 自动登录代理回调
// 自动登录开始回调
-(void)willAutoLoginWithInfo:(NSDictionary *)loginInfo error:(EMError *)error
{
// UIAlertView *alertView = nil;
if (error) {
// alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"prompt", @"Prompt") message:NSLocalizedString(@"login.errorAutoLogin", @"Automatic logon failure") delegate:nil cancelButtonTitle:NSLocalizedString(@"ok", @"OK") otherButtonTitles:nil, nil];
//发送自动登陆状态通知
[[NSNotificationCenter defaultCenter] postNotificationName:KNOTIFICATION_LOGINCHANGE object:@NO];
}
else{
// alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"prompt", @"Prompt") message:NSLocalizedString(@"login.beginAutoLogin", @"Start automatic login...") delegate:nil cancelButtonTitle:NSLocalizedString(@"ok", @"OK") otherButtonTitles:nil, nil];
//将旧版的coredata数据导入新的数据库
EMError *error = [[EaseMob sharedInstance].chatManager importDataToNewDatabase];
if (!error) {
[[EaseMob sharedInstance].chatManager loadDataFromDatabase];
//获取数据
[self loadConversations];
}
}
// [alertView show];
}
// 自动登录结束回调
-(void)didAutoLoginWithInfo:(NSDictionary *)loginInfo error:(EMError *)error
{
// UIAlertView *alertView = nil;
if (error) {
// alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"prompt", @"Prompt") message:NSLocalizedString(@"login.errorAutoLogin", @"Automatic logon failure") delegate:nil cancelButtonTitle:NSLocalizedString(@"ok", @"OK") otherButtonTitles:nil, nil];
//发送自动登陆状态通知
[[NSNotificationCenter defaultCenter] postNotificationName:KNOTIFICATION_LOGINCHANGE object:@NO];
}
else{
//获取群组列表
[[EaseMob sharedInstance].chatManager asyncFetchMyGroupsList];
// alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"prompt", @"Prompt") message:NSLocalizedString(@"login.endAutoLogin", @"End automatic login...") delegate:nil cancelButtonTitle:NSLocalizedString(@"ok", @"OK") otherButtonTitles:nil, nil];
}
// [alertView show];
}
#pragma make - login easemob 用户登录
- (void)loginWithUsername:(NSString *)username
password:(NSString *)password
{
[[EaseMob sharedInstance].chatManager asyncLoginWithUsername:username password:password completion:^(NSDictionary *loginInfo, EMError *error) {
if (!error) {
//设置自动登录
[[EaseMob sharedInstance].chatManager setIsAutoLoginEnabled:YES];
//获取数据
[self loadConversations];
//发送自动登陆状态通知
[[NSNotificationCenter defaultCenter] postNotificationName:KNOTIFICATION_LOGINCHANGE object:@YES];
}
} onQueue:nil];
}
#pragma mark - load conversations 加载会话列表
-(void)loadConversations{
// [[EaseMob sharedInstance].chatManager importDataToNewDatabase];
//获取数据库中数据
[[EaseMob sharedInstance].chatManager loadDataFromDatabase];
// 当前登录用户回话对象列表
NSArray *conversations = [[EaseMob sharedInstance].chatManager conversations];
if (conversations.count == 0) {
//从数据库conversation表获取
conversations = [[EaseMob sharedInstance].chatManager loadAllConversationsFromDatabaseWithAppend2Chat:YES];
}
_conversations = conversations;
}
在会话列表控制器中:
@interface KJAnswerQuestionController ()<UITableViewDataSource,UITableViewDelegate>
/** 所有会话 */
@property (strong,nonatomic)NSArray *arrConversations;
/** 提示视图 */
@property (strong,nonatomic)UIView *showingView;
@end
@implementation KJAnswerQuestionController
- (void)viewDidLoad {
[super viewDidLoad];
//创建tableView
self.view.backgroundColor = HMColor(250, 250, 250);
self.tableView = [[UITableView alloc]initWithFrame:self.view.bounds];
self.tableView.dataSource = self;
self.tableView.delegate = self;
self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero];
[self.view addSubview:self.tableView];
MoveUnderLine(self.tableView);
//创建提示视图
self.showingView = [UIView createViewWithShowingTitle:@"没有聊天记录哟!"];
[self.view addSubview:self.showingView];
//获取数据库中数据
self.arrConversations = [EaseSDKHelper shareHelper].conversations;
[self.tableView reloadData];
//显示隐藏
if (self.arrConversations.count == 0) {
[self.showingView setHidden:NO];
[self.tableView setHidden:YES];
}else{
[self.showingView setHidden:YES];
[self.tableView setHidden:NO];
}
}
//消息刷新
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
NSArray *conversations = [[EaseMob sharedInstance].chatManager conversations];
if (conversations == 0) {
conversations = [[EaseMob sharedInstance].chatManager loadAllConversationsFromDatabaseWithAppend2Chat:YES];
}
if (conversations > self.arrConversations) {
self.arrConversations = conversations;
}
[self.tableView reloadData];
}
#pragma Mark- 数据源方法
//返回行数
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.arrConversations.count;
}
//返回cell
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//取出单个会话
KJContactCell *cell = [KJContactCell createCellWithTableView:tableView];
EMConversation *conversation = [self.arrConversations objectAtIndex:indexPath.row];
cell.conversation = conversation;
return cell;
}
#pragma mark - 代理方法
//设置cell的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 60;
}
//选中cell时的处理
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//取出单个会话
EMConversation *conversation = [self.arrConversations objectAtIndex:indexPath.row];
KJChatViewController *chatVC = [[KJChatViewController alloc]initWithConversationChatter:conversation.chatter conversationType:eConversationTypeChat];
chatVC.title = conversation.chatter;
chatVC.conversation = conversation;
chatVC.conversation.enableUnreadMessagesCountEvent = YES;
[self.navigationController pushViewController:chatVC animated:YES];
}
@end
在聊天控制器中,直接集成ChatViewController
#import "ChatViewController.h"
@interface KJChatViewController : ChatViewController
@end
#import "KJChatViewController.h"
@interface KJChatViewController ()
@end
@implementation KJChatViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
//将未读消息标记为已读
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
// [self.conversation markMessageWithId:self.conversation.chatter asRead:YES];
[self.conversation markAllMessagesAsRead:YES];
}
@end
在自定义的会话列表cell中,显示会话联系人、最后一条记录、时间
#import <UIKit/UIKit.h>
@class KJBadgeButton;
@interface KJContactCell : UITableViewCell
//创建cell
+(instancetype)createCellWithTableView:(UITableView *)tableView;
@property (strong,nonatomic)EMConversation *conversation;
@property (strong,nonatomic)KJBadgeButton *badgeBtn; //提示数字
@end
#import "KJContactCell.h"
#import "KJContact.h"
#import "KJBadgeButton.h"
#define cellBorder 10
#define iconWidth 40
#define textHeight 30
@interface KJContactCell()
@property (strong,nonatomic)UIImageView *iconView; //头像
@property (strong,nonatomic)UILabel *MainTextLabel; //姓名
@property (strong,nonatomic)UILabel *subTextLabel; //消息
@end
@implementation KJContactCell
static NSString *reuseIdentifier = @"Cell";
+(instancetype)createCellWithTableView:(UITableView *)tableView{
KJContactCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (!cell) {
cell = [[KJContactCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier];
}
cell.detailTextLabel.textColor = HMColor(153, 153, 153);
cell.detailTextLabel.font = fontSize_13;
return cell;
}
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//1.头像
self.iconView = [[UIImageView alloc]init];
[self.contentView addSubview:self.iconView];
//2.提示badge
self.badgeBtn = [[KJBadgeButton alloc]initWithFrame:CGRectMake(cellBorder+iconWidth-10, 5, 15, 15)];
[self.contentView addSubview:self.badgeBtn];
//3.姓名
self.MainTextLabel = [[UILabel alloc]init];
self.MainTextLabel.textColor = HMColor(51, 51, 51);
self.MainTextLabel.font = fontSize_14;
[self.contentView addSubview:self.MainTextLabel];
//4.消息
self.subTextLabel = [[UILabel alloc]init];
self.subTextLabel.textColor = HMColor(153, 153, 153);
self.subTextLabel.font = fontSize_13;
[self.contentView addSubview:self.subTextLabel];
}
return self;
}
-(void)layoutSubviews{
[super layoutSubviews];
//1.头像
self.iconView.frame = CGRectMake(cellBorder, cellBorder, iconWidth, iconWidth);
//2.姓名
self.MainTextLabel.frame = CGRectMake(CGRectGetMaxX(self.iconView.frame)+2*cellBorder, 2, 100, textHeight);
//3.消息
self.subTextLabel.frame =CGRectMake(CGRectGetMaxX(self.iconView.frame)+2*cellBorder, CGRectGetMaxY(self.MainTextLabel.frame), SCREEN_WIDTH-CGRectGetMaxX(self.iconView.frame)-cellBorder, textHeight);
}
//接收联系人数据
-(void)setConversation:(EMConversation *)conversation{
_conversation = conversation;
//设置头像
self.iconView.image = [UIImage imageNamed:@"head"];
//设置姓名
self.MainTextLabel.text = conversation.chatter;
//设置提示数字
[self.badgeBtn setBadgeValue:[NSString stringWithFormat:@"%ld",conversation.unreadMessagesCount]];
//设置历史消息
self.subTextLabel.text = [self latestMessageTitleForConversation:conversation];
//设置历史消息时间
self.detailTextLabel.text = [self latestMessageTimeForConversation:conversation];
}
#pragma mark - 最后一条消息展示内容
-(NSString *)latestMessageTitleForConversation:(EMConversation *)conversation
{
//用户获取最后一条message,根据message的messageBodyType展示显示最后一条message对应的文案
NSString *latestMessageTitle = @"";
EMMessage *lastMessage = [conversation latestMessage];
if (lastMessage) {
id<IEMMessageBody> messageBody = lastMessage.messageBodies.lastObject;
switch (messageBody.messageBodyType) {
case eMessageBodyType_Image:{
latestMessageTitle = NSLocalizedString(@"message.image1", @"[image]");
} break;
case eMessageBodyType_Text:{
// 表情映射。
NSString *didReceiveText = [EaseConvertToCommonEmoticonsHelper
convertToSystemEmoticons:((EMTextMessageBody *)messageBody).text];
latestMessageTitle = didReceiveText;
} break;
case eMessageBodyType_Voice:{
latestMessageTitle = NSLocalizedString(@"message.voice1", @"[voice]");
} break;
case eMessageBodyType_Location: {
latestMessageTitle = NSLocalizedString(@"message.location1", @"[location]");
} break;
case eMessageBodyType_Video: {
latestMessageTitle = NSLocalizedString(@"message.video1", @"[video]");
} break;
case eMessageBodyType_File: {
latestMessageTitle = NSLocalizedString(@"message.file1", @"[file]");
} break;
default: {
} break;
}
}
return latestMessageTitle;
}
#pragma mark - 最后一条消息展示时间
- (NSString *)latestMessageTimeForConversation:(EMConversation *)conversation
{
//用户获取最后一条message,根据lastMessage中timestamp,自定义时间文案显示(例如:"1分钟前","14:20")
NSString *latestMessageTime = @"";
EMMessage *lastMessage = [conversation latestMessage];;
if (lastMessage) {
latestMessageTime = [NSDate formattedTimeFromTimeInterval:lastMessage.timestamp];
}
return latestMessageTime;
}
@end
消息提醒按钮
#import <UIKit/UIKit.h>
@interface KJBadgeButton : UIButton
@property (nonatomic, copy) NSString *badgeValue;
@end
#import "KJBadgeButton.h"
@implementation KJBadgeButton
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.hidden = YES;
self.userInteractionEnabled = NO;
[self setBackgroundImage:[UIImage resizedImageWithName:@"main_badge"] forState:UIControlStateNormal];
self.titleLabel.font = [UIFont systemFontOfSize:11];
}
return self;
}
- (void)setBadgeValue:(NSString *)badgeValue
{
#warning copy
// _badgeValue = badgeValue;
_badgeValue = [badgeValue copy];
if (badgeValue && [badgeValue intValue] != 0) {
self.hidden = NO;
// 设置文字
[self setTitle:badgeValue forState:UIControlStateNormal];
// 设置frame
CGRect frame = self.frame;
CGFloat badgeH = self.currentBackgroundImage.size.height;
CGFloat badgeW = self.currentBackgroundImage.size.width;
if (badgeValue.length > 1) {
// 文字的尺寸
CGSize badgeSize = [badgeValue sizeWithFont:self.titleLabel.font];
badgeW = badgeSize.width + 10;
}
frame.size.width = badgeW;
frame.size.height = badgeH;
self.frame = frame;
} else {
self.hidden = YES;
}
}
@end
最后在TabbarController中检测未读消息
//注册代理,监听未读消息数
[[EaseMob sharedInstance].chatManager addDelegate:self delegateQueue:nil];
#pragma mark - EMChatManagerChatDelegate
/**
* 历史会话列表更新了会调用
*/
- (void)didUpdateConversationList:(NSArray *)conversationList
{
// 给数据源重新赋值
self.arrConversations = conversationList;
//刷新表格
[self.messageVc.tableView reloadData];
// 显示总的未读数
[self showTabBarBadge];
}
/**
* 未读消息数改变了会调用
*/
- (void)didUnreadMessagesCountChanged
{
//刷新表格
[self.messageVc.tableView reloadData];
// 显示总的未读数
[self showTabBarBadge];
}
/**
* 将总的未读消息数显示到tabBar上
*/
- (void)showTabBarBadge
{
NSInteger totalUnreadCount = 0;
for (EMConversation *conversation in self.arrConversations) {
//获取所有的联系人发来的未读消息
totalUnreadCount += [conversation unreadMessagesCount];
}
if (totalUnreadCount > 0) {
self.messageVc.tabBarItem.badgeValue = [NSString stringWithFormat:@"%ld",totalUnreadCount];
UIApplication *application = [UIApplication sharedApplication];
[application setApplicationIconBadgeNumber:totalUnreadCount];
}else{
self.messageVc.tabBarItem.badgeValue = nil;
UIApplication *application = [UIApplication sharedApplication];
[application setApplicationIconBadgeNumber:0];
}
}
-(void)dealloc{
[[EaseMob sharedInstance].chatManager removeDelegate:self];
}
测试后:
标签:
原文地址:http://www.cnblogs.com/XYQ-208910/p/5396635.html