这是本文档旧的修订版!


CEC iOS SDK集成(自定义UI)

不使用环信提供的客服UI,可以参考下面的集成文档。

下载SDK

官网下载 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 中会自动增加。

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 <HelpDesk/HelpDesk.h>
#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<HCallManagerDelegate>)#> delegateQueue:nil];
//移除代理
[[HChatClient sharedClient].callManager removeDelegate:<#(id<HCallManagerDelegate>)#>];

音视频 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) {}];