码迷,mamicode.com
首页 > 移动开发 > 详细

iOS:集成环信EaseMobSDK单聊功能

时间:2016-04-15 20:19:32      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:

当然在集成环信之前需要一些准备操作:

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];
}

测试后:

技术分享 技术分享

 

iOS:集成环信EaseMobSDK单聊功能

标签:

原文地址:http://www.cnblogs.com/XYQ-208910/p/5396635.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!