zoukankan      html  css  js  c++  java
  • iOS:集成环信EaseMobSDK单聊功能

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

    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;
    }
    View Code

    在会话列表控制器中:

    @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
    View Code

    在聊天控制器中,直接集成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
    View Code

    在自定义的会话列表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
    View Code

    消息提醒按钮

    #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
    View Code

    最后在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];
        }
    }
    View Code
    //移除代理
    -(void)dealloc{ [[EaseMob sharedInstance].chatManager removeDelegate:self]; }

    测试后:

     

    以上只是实现了单聊和群聊的功能,那么实时语音和视频如何实现呢,下面这个就是干货:

    1.集成实时通话的前提是集成好单聊,并且使用的是libEaseMobClientSDK.a包,因为这个包 包含实时通话的功能
    2.将demo3.0中的Call文件(实时通话的界面)以及Resources(通话界面的资源图片)加到你自己的工程中
    3.点击实时通话或者视频的按钮,实际是发起的通知,在你工程中的主控制器中监听这个通知,在通知的方法中实现发起实时通话的方法以及跳转到通话界面
    4.接收实时通话的回调是  - (void)callSessionStatusChanged:(EMCallSession *)callSession changeReason:(EMCallStatusChangedReason)reason error:(EMError *)error  
    5.实时通话用的协议是:EMCallManagerDelegate    代理:[[EaseMob sharedInstance].callManager addDelegate:self delegateQueue:nil];
    6.具体添加哪些方法看下上传的ViewController文件,按照这个文件中的方法加到自己的主控制器中,demo中的实现在MainViewController.m类

    代码如下:

    记得先导入call文件:这个是用来进行视频和电话语音的类

    ViewController.docx文件:http://i.cnblogs.com/Files.aspx

    #import "ChatViewController.h"
    @interface KJChatViewController : ChatViewController
    @end
    
    
    #import "KJChatViewController.h"
    #import "CallViewController.h"
    @interface KJChatViewController ()<EMCallManagerDelegate>
    @end
    @implementation KJChatViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 实时通话的代理
        [self registerNotifications];
        
        // 监听发起实时通话的通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callOutWithChatter:) name:@"callOutWithChatter" object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callControllerClose:) name:@"callControllerClose" object:nil];
    }
    
    //将未读消息标记为已读
    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
        //    [self.conversation markMessageWithId:self.conversation.chatter asRead:YES];
        [self.conversation markAllMessagesAsRead:YES];
    }
    
    
    -(void)registerNotifications
    {
        [self unregisterNotifications];
        
        [[EaseMob sharedInstance].callManager addDelegate:self delegateQueue:nil];
    }
    
    -(void)unregisterNotifications
    {
        
        [[EaseMob sharedInstance].callManager removeDelegate:self];
    }
    
    - (void)dealloc
    {
        [self unregisterNotifications];
    }
    
    // 发起实时通话
    - (void)callOutWithChatter:(NSNotification *)notification
    {
        id object = notification.object;
        if ([object isKindOfClass:[NSDictionary class]]) {
            if (![self canRecord]) {
                return;
            }
            
            EMError *error = nil;
            NSString *chatter = [object objectForKey:@"chatter"];
            EMCallSessionType type = [[object objectForKey:@"type"] intValue];
            EMCallSession *callSession = nil;
            if (type == eCallSessionTypeAudio) {
                callSession = [[EaseMob sharedInstance].callManager asyncMakeVoiceCall:chatter timeout:50 error:&error];
            }
            else if (type == eCallSessionTypeVideo){
                if (![CallViewController canVideo]) {
                    return;
                }
                callSession = [[EaseMob sharedInstance].callManager asyncMakeVideoCall:chatter timeout:50 error:&error];
            }
            
            if (callSession && !error) {
                [[EaseMob sharedInstance].callManager removeDelegate:self];
                
                CallViewController *callController = [[CallViewController alloc] initWithSession:callSession isIncoming:NO];
                callController.modalPresentationStyle = UIModalPresentationOverFullScreen;
                [self presentViewController:callController animated:NO completion:nil];
            }
            
            if (error) {
                UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"error", @"error") message:error.description delegate:nil cancelButtonTitle:NSLocalizedString(@"ok", @"OK") otherButtonTitles:nil, nil];
                [alertView show];
            }
        }
    }
    
    #pragma mark - call
    
    - (BOOL)canRecord
    {
        __block BOOL bCanRecord = YES;
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending)
        {
            if ([audioSession respondsToSelector:@selector(requestRecordPermission:)]) {
                [audioSession performSelector:@selector(requestRecordPermission:) withObject:^(BOOL granted) {
                    bCanRecord = granted;
                }];
            }
        }
        
        if (!bCanRecord) {
            UIAlertView * alt = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"setting.microphoneNoAuthority", @"No microphone permissions") message:NSLocalizedString(@"setting.microphoneAuthority", @"Please open in "Setting"-"Privacy"-"Microphone".") delegate:self cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"ok", @"OK"), nil];
            [alt show];
        }
        
        return bCanRecord;
    }
    
    
    
    #pragma mark - ICallManagerDelegate
    
    // 接收实时通话的回调函数
    - (void)callSessionStatusChanged:(EMCallSession *)callSession changeReason:(EMCallStatusChangedReason)reason error:(EMError *)error
    {
        if (callSession.status == eCallSessionStatusConnected)
        {
            EMError *error = nil;
            do {
                BOOL isShowPicker = [[[NSUserDefaults standardUserDefaults] objectForKey:@"isShowPicker"] boolValue];
                if (isShowPicker) {
                    error = [EMError errorWithCode:EMErrorInitFailure andDescription:NSLocalizedString(@"call.initFailed", @"Establish call failure")];
                    break;
                }
                
                if (![self canRecord]) {
                    error = [EMError errorWithCode:EMErrorInitFailure andDescription:NSLocalizedString(@"call.initFailed", @"Establish call failure")];
                    break;
                }
                
    #warning 在后台不能进行视频通话
                if(callSession.type == eCallSessionTypeVideo && ([[UIApplication sharedApplication] applicationState] != UIApplicationStateActive || ![CallViewController canVideo])){
                    error = [EMError errorWithCode:EMErrorInitFailure andDescription:NSLocalizedString(@"call.initFailed", @"Establish call failure")];
                    break;
                }
                
                if (!isShowPicker){
                    [[EaseMob sharedInstance].callManager removeDelegate:self];
                    CallViewController *callController = [[CallViewController alloc] initWithSession:callSession isIncoming:YES];
                    callController.modalPresentationStyle = UIModalPresentationOverFullScreen;
                    [self presentViewController:callController animated:NO completion:nil];
                    
                    // EaseMessageViewController是聊天类,根据自己的聊天类写
                    if ([self.navigationController.topViewController isKindOfClass:[EaseMessageViewController class]])
                    {
                        EaseMessageViewController *chatVc = (EaseMessageViewController *)self.navigationController.topViewController;
                        chatVc.isViewDidAppear = NO;
                    }
                }
            } while (0);
            
            if (error) {
                [[EaseMob sharedInstance].callManager asyncEndCall:callSession.sessionId reason:eCallReasonHangup];
                return;
            }
        }
    }
    
    
    - (void)callControllerClose:(NSNotification *)notification
    {
        //    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        //    [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
        //    [audioSession setActive:YES error:nil];
        
        [[EaseMob sharedInstance].callManager addDelegate:self delegateQueue:nil];
    }
    
    @end
    View Code

    演示结果如下:经本人测试,在真机上运行没有问题,实时语音视频聊天均能够实现

    左边为电话通话                  右边为视频通话

     

    以下为参考资料:

    1.基于环信Demo3.0,实现单聊功能:http://www.jianshu.com/p/f53be9664f14

    2.集成环信的即时通讯:http://www.jianshu.com/p/b4618ef39274

    3.环信聊天界面 - 显示历史会话记录http://blog.csdn.net/github_26672553/article/details/50719487

    4.环信集成 - 加载会话列表http://blog.csdn.net/u010545480/article/details/49660255

    5.扩展表情包:http://apps.timwhitlock.info/emoji/tables/unicode 

    其他demo下载: https://github.com/zyprosoft/ZYChat

    集成视频:http://www.imgeek.org/video/

    github:https://github.com/xiayuanquan/EaseMobChat

    本人原创,转载须注明出处,谢谢!

  • 相关阅读:
    洛谷 P1200.[USACO1.1]你的飞碟在这儿Your Ride Is Here
    洛谷 P1055.ISBN号码
    洛谷 P1567.统计天数
    洛谷 P2141.珠心算测验
    洛谷 P1428.小鱼比可爱
    洛谷 P1427.小鱼的数字游戏
    洛谷 P1047.校门外的树
    洛谷 P1046.陶陶摘苹果
    洛谷 P1980.计数问题
    洛谷 P1424.小鱼的航程(改进版)
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/5396635.html
Copyright © 2011-2022 走看看