====== CEC iOS SDK集成(自定义UI) ====== 不使用环信提供的客服UI,可以参考下面的集成文档。 ===== 下载SDK ===== 从[[http://www.easemob.com/download|官网]]下载 **iOS客服访客端SDK** 下载后有三个目录: * BaseFramework: 包含 HyphenateLite.framework,是项目依赖库。 * HelpDeskFramework: HelpDesk.framework 和 HelpDeskLite.framework,HelpDesk.framework 包含实时视频功能,HelpDeskLite.framework不包含实时视频功能。 * kefu-ios-demo: 基于访客端SDK开发的演示商城Demo,可直接运行。 ===== 环境准备 ===== (以下以集成包含音视频的HelpDesk.framework为例,HelpDeskLite.framework 同理) 1、在工程中导入 HelpDesk.framework、HyphenateLite.framework和 HelpDeskUI 文件夹。两种方式: * 将上述文件夹拖入工程,在弹出对话框中勾选“Copy items if needed”和“Create groups”,并点击“Finish”; * 或者,选择“File > Add Files to”,从本地选择上述文件夹,点击“Options”,勾选“Copy items if needed”和“Create groups”,并点击“Add”。 2、选中当前的TARGET,向 General -> Embedded Binaries 中添加以上两个依赖库。Linked Frameworks and Libraries 中会自动增加。 {{:cs:300visitoraccess:frameworkimport.png?nolink&600|}} 3、向Build Settings -> Linking -> Other Linker Flags 中增加-ObjC(注意区分大小写)。 4、SDK 暂不支持bitcode,在Build Settings ->Enable Bitcode 改为NO。 5、在工程info.plist文件中,增加隐私权限: * Privacy - Photo Library Usage Description 需要访问您的相册 * Privacy - Microphone Usage Description 需要访问您的麦克风 * Privacy - Camera Usage Description 需要访问您的摄像机 6、在pch文件或全局.h文件中添加如下代码: #ifdef __OBJC__ #import #endif ===== 初始化 ===== HOptions *option = [[HOptions alloc] init]; option.appkey = @"Your appkey"; // 必填项,appkey获取地址:kefu.easemob.com,“管理员模式 > 渠道管理 > 手机APP”页面的关联的“AppKey” option.tenantId = @"Your tenantId";// 必填项,tenantId获取地址:kefu.easemob.com,“管理员模式 > 设置 > 企业信息”页面的“租户ID” //推送证书名字 option.apnsCertName = @"your apnsCerName";//(集成离线推送必填) //Kefu SDK 初始化,初始化失败后将不能使用Kefu SDK HError *initError = [[HChatClient sharedClient] initializeSDKWithOptions:option]; if (initError) { // 初始化错误 } ===== APNs 推送 ===== //注册APNs推送 [application registerForRemoteNotifications]; UIUserNotificationType notificationTypes = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert; UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil]; [application registerUserNotificationSettings:settings]; 您注册了推送功能,iOS 会自动回调以下方法,得到 deviceToken,您需要将 deviceToken 传给 SDK。 // 将得到的deviceToken传给SDK - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{ [[HChatClient sharedClient] bindDeviceToken:deviceToken]; } // 注册deviceToken失败 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{ NSLog(@"error -- %@",error); } ** APNs注册失败,一般是由于使用了通用证书或者是模拟器调试导致,请检查证书并用真机调试。此处是 iOS 系统报的错,如仍不能确定,请从网上查找相关资料。** ===== 登录登出 ===== 由于HChatClient有一个isLoggedInBefore(BOOL),判断是否已经登录,登录操作前可以先做个判断。 HChatClient *client = [HChatClient sharedClient]; client.isLoggedInBefore //是否已经登录 client.currentUsername //已登录账号,如果与需要登录不符合,可先调用退出 HError *error = [client loginWithUsername:@"username" password:@"password"]; HError *error = [[HChatClient sharedClient] logout:YES]; //参数为是否解除device token的绑定 ===== 绑定服务号 ===== //进入聊天界面需要绑定im服务号 [[HChatClient sharedClient].chatManager bindChatWithConversationId:<#(IM 服务号)#>]; //聊天界面销毁的时候需要解除绑定 [[HChatClient sharedClient].chatManager unbind]; ===== 发送消息 ===== HMessage *message = [HMessage createTxtSendMessageWithContent:<#(文本消息内容)#> to:<#(IM 服务号)#>]; //创建文本消息 HMessage *message = [HMessage createImageSendMessageWithData:<#(图片数据)#> displayName:<#(图片名字)#> to:<#(IM 服务号)#>];//创建图片消息 HMessage *message = [HMessage createVoiceSendMessageWithLocalPath:<#(语音文件路径)#> duration:<#(语音长度,秒int)#> to:<#(IM 服务号)#>];//创建语音消息 HMessage *message = [HMessage createVideoInviteSendMessageWithContent:<#(内容)#> to:<#(IM 服务号)#>];//发起音视频消息 HMessage *message = [HMessage createLocationSendMessageWithLatitude:<#(纬度)#> longitude:<#(经度)#> address:<#(地址)#> to:<#(IM 服务号)#>]; 发送消息 [[HChatClient sharedClient].chatManager sendMessage:<#(HMessage*)#> progress:nil completion:^(HMessage *message, HError *error) {}]; ===== 收消息监听 ===== //添加消息听 [[HChatClient sharedClient].chatManager addDelegate:<#(接收回调的类)#> delegateQueue:nil]; //移除消息监听 [[HChatClient sharedClient].chatManager removeDelegate:<#(接收回调的类)#>]; //收到消息 - (void)messagesDidReceive:(NSArray *)aMessages; //入库 //收到透传消息 - (void)cmdMessagesDidReceive:(NSArray *)aCmdMessages;//不入库 //消息状态改变 - (void)messageStatusDidChange:(HMessage *)aMessage error:(HError *)aError; ===== 获取消息详情 ===== HMessage *message; if(message.body.type == EMMessageBodyTypeText) { //文本消息 EMTextMessageBody *body = (EMTextMessageBody*)message.body; NSString *content = body.text; } if(message.body.type == EMMessageBodyTypeImage) {//图片消息 EMImageMessageBody *body = (EMImageMessageBody *)message.body; NSString *localPath = body.localPath; //本地路径 NSString *remotePath = body.remotePath; //远程路径 } if(message.body.type == EMMessageBodyTypeVoice) {//语音消息 EMVoiceMessageBody *body = (EMVoiceMessageBody *)message.body; NSString *localPath = body.localPath; //本地路径 NSString *remotePath = body.remotePath; //远程路径 } if(message.body.type == EMMessageBodyTypeFile) {//文件消息 EMFileMessageBody *body = (EMFileMessageBody *)message.body; NSString *displayName = body.displayName;//文件名称 long long fileLength = body.fileLength;//文件大小,单位:Byte NSString *localPath = body.localPath; //本地路径 NSString *remotePath = body.remotePath; //远程路径 } if(message.body.type == EMMessageBodyTypeLocation) {//地址消息 EMLocationMessageBody *body = (EMLocationMessageBody *)message.body; double latitude = body.latitude;//纬度 double longitude = body.longitude;//经度 NSString *address = body.address;//地点名称 } if(message.body.type == EMMessageBodyTypeCmd) {//命令消息 EMCmdMessageBody *body = (EMCmdMessageBody *)message.body; NSString *action = body.action; //命令内容 } ===== 实时音视频 ===== //初始化音视频 HCallOptions *options = [[HCallOptions alloc] init]; options.videoOff = NO; //是否关闭摄像头 options.mute = NO; //是否静音 options.previewView = <#(HCallLocalView *)#>;//本地预览view [[HChatClient sharedClient].callManager setCallOptions:options]; //添加视频代理 [[HChatClient sharedClient].callManager addDelegate:<#(id)#> delegateQueue:nil]; //移除代理 [[HChatClient sharedClient].callManager removeDelegate:<#(id)#>]; ===== 音视频 API ===== //接收坐席发来视频邀请 [[HChatClient sharedClient].callManager acceptCallWithNickname:<#(自己昵称)#> completion:^(id obj, HError *error) {}]; #pragma mark - HCallManagerDelegate //收到一个视频通话请求,参数为请求者昵称 - (void)onCallReceivedNickName:(NSString *)nickName; //有成员进入会话 - (void)onMemberJoin:(HCallMember *)member; //成员离开 - (void)onMemberExit:(HCallMember *)member; //有视频流进来 - (void)onStreamAdd:(HCallStream *)stream; //视频流被移除[不包括自己] - (void)onStreamRemove:(HCallStream *)stream; //视频流刷新 - (void)onStreamUpdate:(HCallStream *)stream; //视频通话结束 - (void)onCallEndReason:(int)reason desc:(NSString *)desc; //视频通话已经结束 - (void)callDidEnd:(HCallSession *)aSession reason:(HCallEndReason)aReason error:(HError *)aError; #pragma - mark 操作 //接受视频请求 [[HChatClient sharedClient].callManager acceptCallCompletion:^(id obj, HError *error) {}]; //拒绝视频请求 [[HChatClient sharedClient].callManager endCall]; //挂断视频请求 [[HChatClient sharedClient].callManager endCall]; //切换镜头 [[HChatClient sharedClient].callManager switchCameraPosition:YES]; //默认前置摄像头(YES) //关闭麦克风 [[HChatClient sharedClient].callManager pauseVoice]; //打开麦克风 [[HChatClient sharedClient].callManager resumeVoice]; //关闭本地视频传输 [[HChatClient sharedClient].callManager pauseVideo]; //打开本地视频传输 [[HChatClient sharedClient].callManager resumeVideo]; //订阅成员视频 [[HChatClient sharedClient].callManager subscribeStreamId:<#(streamId)#> view:<#(HCallRemoteView*)#> completion:^(id obj, HError *error) {}]; //取消订阅 [[HChatClient sharedClient].callManager unSubscribeStreamId:streamId completion:^(id obj, HError *error) {}];