====== VEC iOS SDK集成 ====== 环信客服云(Customer Engagement Cloud, CEC)现已推出专属 iOS SDK!您只需在客服云创建 APP 关联,并按照本文档的步骤集成 iOS SDK,即可轻松实现 iOS 版 APP 接入。 ===== SDK介绍 ===== **iOS SDK 支持以下功能:** * 发送文本消息、语音消息、图片消息、位置消息、视频消息。 * 接收文本消息、语音消息、图片消息、位置消息、视频消息、文件消息、机器人菜单等。 * 显示客服头像和昵称、显示机器人转人工按钮。 * 发送消息附带访客信息,指定客服、指定技能组(参考[[#第4步_集成更多业务功能|第4步:集成更多业务功能]])。 * 支持留言功能,包括文字、图片和语音留言(参考[[#第5步_集成更多扩展功能|第5步:集成更多扩展功能]])。 **客户端与服务端连接方式:** 客户端与服务端的连接方式包含[[cs:300visitoraccess:persistent-connection|长连接(永久)和长连接(24小时)]]。长连接(永久)包含Socket通道,能够保证客户端无论是否在线,都能够收到消息和通知;长连接(24小时)是仅有24小时时效的长连接,同样包含Socket通道,在时效内与长连接拥有相同的通信能力。 环信客服云默认采用“长连接(24小时)”方式与Android/iOS客户端对接。“长连接(永久)”方式为增值服务,如需开通,请联系环信商务经理。 **如果您是im和客服一起使用,也需要联系环信商务经理进行开通。** ===== 集成方式 ===== CEC iOS SDK已集成双通道功能,确保不丢消息;并提供会话相关内置UI,集成客服云通用功能,只需5分钟。如果您使用内置UI,请参考本文档集成;如果您不使用环信提供的内置UI,请参考:[[cs:300visitoraccess:iossdk-customui|CEC iOS SDK集成(自定义UI)]] ===== 第1步:创建APP关联 ===== 客服云的“APP关联”对应即时通讯云(IM)后台的应用。在客服云创建关联后,可直接登录IM后台管理该关联对应的应用。 * 如果您还没有环信即时通讯云的账号,可以打开[[http://kefu.sh.absoloop.com/mo/login|环信客服云]],进入“管理员模式 > 渠道管理 > 手机APP”,快速创建一个“APP关联”; * 如果您已有环信即时通讯云的账号并创建了应用,可以打开[[http://kefu.sh.absoloop.com/mo/login|环信客服云]](并使用客服云账号登录),进入“管理员模式 > 渠道管理 > 手机APP”,关联您的IM账号。 关于创建APP关联的分步骤演示,请参考:[[cs:300visitoraccess:createappchannel|创建APP关联]]。 ===== 第2步:环境准备 ===== 开发工具:Xcode。 === 客服SDK 下载 === 集成CEC iOS SDK时,可参考“商城”demo源码和HelpDeskUI源码。 首先要下载环信提供的客服SDK,下载地址:[[http://www.easemob.com/download/cs]](下载"iOS客服访客端SDK") === 客服SDK 介绍 === 下载的客服SDK目录包括imsdk、sdk、kefu-ios-demo 三个文件夹: * **sdk** 访客端sdk,HelpDesk.framework * ** imsdk** 访客sdk的依赖库,HyphenateChat.framework,使用时要与sdk目录中的HelpDesk.framework配对使用。 * **kefu-ios-demo** 访客端demo,工程里边包含demo源码和HelpDeskUI源码 下载后可直接双击CustomerSystem-ios.xcworkspace运行。 ===== 第3步:集成基础功能 ===== 完成该步骤可以实现用户注册、登录、退出,向客服云系统发送文本、语音、图片、文件消息功能。 ==== 准备工作 ==== ** 1、在工程中导入 HelpDesk.framework、HyphenateChat.framework文件,两种方式** * 将上述文件夹拖入工程,在弹出对话框中勾选“Copy items if needed”和“Create groups”,并点击“Finish”; * 或者,选择“File > Add Files to”,从本地选择上述文件夹,点击“Options”,勾选“Copy items if needed”和“Create groups”,并点击“Add”。 ** 2、选中当前的TARGET,向 General → Frameworks,Libraries,and Embedded Binaries 中添加依赖库。要将'Do Not Embed'改成'Embed & Sign'。** {{:cs:300visitoraccess:文件名称.jpg?nolink&800|}} ** 3、在工程info.plist文件中,增加隐私权限:** * Privacy - Photo Library Usage Description 需要访问您的相册 * Privacy - Microphone Usage Description 需要访问您的麦克风 * Privacy - Camera Usage Description 需要访问您的摄像机 * Privacy - Location Always Usage Description 发送定位消息的时候需要访问您的位置信息 * Privacy - Location When In Use Usage Description 发送定位消息的时候需要访问您的位置信息 ** 4、如果有国际化话需求还需要把国际化文件里边的内容复制出来放到自己工程的国际化文件内** {{:cs:300visitoraccess:localizable.png?400|}} ** 5、在pch文件或全局.h文件中添加如下代码:** #ifdef __OBJC__ #import #endif 注: * 如果工程中没有pch文件,需要新建一个,并在Build Settings中设置Prefix Header为该pch文件,例如:HelloiOS/PrefixHeader.pch。 * HelpDeskUI是环信提供的一个ui库,在kefu-ios-demo/CustomerSystem-ios/HelpDeskUI路径中,集成环信HelpDeskUI的时候,由于HelpDeskUI内部使用了第三方库,如果与开发者第三方库产生冲突,可将HelpDeskUI中冲突的第三方库删除,如果第三方库中的接口有升级的部分,请酌情进行升级。 ==== 集成环信UI库 ==== 请移步到ui库文档http://docs.easemob.com/cs/300visitoraccess/iosdemo-1 ==== 初始化 ==== 在 ''AppDelegate.m'' 文件的系统回调 ''didFinishLaunchingWithOptions'' 中,调用初始化接口。 ** 1、初始化sdk** HDOptions *option = [[HDOptions alloc] init]; // 必填项,appkey获取地址:kefu.sh.absoloop.com,“管理员模式 > 接入管理 > 在线客服 > APP > 关联app信息页面的关联的“AppKey” option.appkey = @"Your appkey"; // 必填项,tenantId获取地址:kefu.sh.absoloop.com,“管理员模式 > 账户 > 账户信息 > 租户ID一栏的数据” option.tenantId = @"Your tenantId"; // 如果使用VEC相关功能需要必填configId 获取地址:kefu.sh.absoloop.com,“管理员模式 > 接入管理 > 视频客服 > APP > 插件信息页面的“ConfigId” option.tenantId = @"Your configId"; //推送证书名字集成离线推送必填) option.apnsCertName = @"your apnsCerName"; //Kefu SDK 初始化,初始化失败后将不能使用Kefu SDK HDError *initError = [[HDClient sharedClient] initializeSDKWithOptions:option]; if (initError) { // 初始化错误 } //如果是imsdk 和 客服sdk 共存使用 场景 觉得HDOptions 不满足im EMOptions 参数的请使用initializeSDKWithOptions:withToImoptions:进行初始化 EMOptions * imOptions =[EMOptions optionsWithAppkey:option.appkey]; imOptions.enableFpa = YES;// 设置对应的im参数 imOptions.usingHttpsOnly = NO; //设置对应的im参数 HDError *initError = [[HDClient sharedClient] initializeSDKWithOptions:option withToImoptions:imOptions]; if (initError) { // 初始化错误 } //⚠️ 注意 如果使用了im sdk 提供的UI库 一定要初始化如下这个方法 [EaseIMKitManager initWithEMOptions:nil]; ** 2、初始化自定义小表情** [[HDEmotionEscape sharedInstance] setEaseEmotionEscapePattern:@"\\[[^\\[\\]]{1,3}\\]"]; [[HDEmotionEscape sharedInstance] setEaseEmotionEscapeDictionary:[HDConvertToCommonEmoticonsHelper emotionsDictionary]]; ** 3、其他初始化细节可以参考demo中的如下类** {{:cs:300visitoraccess:initappdelegate.png?400|}} 注:私有部署场景下,需要在初始化方法中额外配置服务器IP地址和端口,请参考:[[cs:300visitoraccess:private-server|访客端SDK私有部署集成]] ==== APNs离线推送 ==== 推送证书制作和上传,请参考[http://docs-im.easemob.com/im/ios/apns/deploy] {{:cs:300visitoraccess:easemobapp.jpg?600|}} 您可以直接从渠道管理中对应的app直接进入对应的im关联后台。 //注册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{ [[HDClient sharedClient] bindDeviceToken:deviceToken]; } // 注册deviceToken失败 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{ NSLog(@"error -- %@",error); } ** APNs注册失败,一般是由于使用了通用证书或者是模拟器调试导致,请检查证书并用真机调试。此处是 iOS 系统报的错,如仍不能确定,请从网上查找相关资料。** ==== 注册 ==== 注册建议在服务端创建,而不要放到APP中,可以在登录自己APP时从返回的结果中获取环信账号再登录环信服务器。 HDError *error = [[HDClient sharedClient] registerWithUsername:@"username" password:@"password"]; error.code: HDErrorNetworkUnavailable 网络不可用 HDErrorUserAlreadyExist 用户已存在 HDErrorUserAuthenticationFailed 无开放注册权限(后台管理界面设置[开放|授权]) HDErrorUserIllegalArgument 用户名非法 ==== 登录 ==== 由于HDClient有一个- (void)getIsLoggedInBeforeCompletion:(void (^)(BOOL isLoggedInBefore))aCompletionBlock;登录操作前可以先做个判断。 [[HDClient sharedClient] getIsLoggedInBeforeCompletion:^(BOOL isLoggedInBefore) { dispatch_async(dispatch_get_main_queue(), ^{ if (isLoggedInBefore) { // 进入会话页面 // 获取地址:kefu.sh.absoloop.com,“管理员模式 > 渠道管理 > 手机APP”页面的关联的“IM服务号” HDMessageViewController *chatVC = [[HDMessageViewController alloc] initWithConversationChatter:@"IM 服务号"]; [self.navigationController pushViewController:chatVC animated:YES]; }else{ //需要登陆 } }); }]; ==== 退出 ==== 登出后则无法收到客服发来的消息。 //参数为是否解绑推送的devicetoken HDError *error = [[HDClient sharedClient] logout:YES]; if (error) { //登出出错 } else {//登出成功 } ==== 获取会话 ==== **注意:** ServiceIMNumber(IM服务号)由于服务器忽略大小写,IM服务号必须是小写,**在配置界面的IM服务号请使用小写**。 //获取一个会话 HDConversation *conversation = [[HDClient sharedClient].chatManager getConversation:@"IM 服务号"]; //获取地址:kefu.sh.absoloop.com,“管理员模式 > 渠道管理 > 手机APP”页面的关联的“IM服务号” ==== 判断登录状态 ==== //1、异步方法 [[HDClient sharedClient] getIsLoggedInBeforeCompletion:^(BOOL isLoggedInBefore) { if (isLoggedInBefore) { // 已登陆 }else{ //未登录 } }]; //2、同步方法 会阻塞线程 if ([[HDClient sharedClient] getIsLoggedInBefore]) { //已登陆 }else{ //未登录 } ==== 添加网络监听 ==== 添加网络监听,可以显示当前是否连接服务器。 //添加网络监控,一般在app初始化的时候添加监控,第二个参数是执行代理方法的队列,默认是主队列 [[HDClient sharedClient] addDelegate:self delegateQueue:nil]; //移除网络监控 [[HDClient sharedClient] removeDelegate:self]; /* 有以下几种情况, 会引起该方法的调用: * 1. 登录成功后, 手机无法上网时, 会调用该回调 * 2. 登录成功后, 网络状态变化时, 会调用该回调*/ - (void)connectionStateDidChange:(HConnectionState)aConnectionState { switch (aConnectionState) { case HConnectionConnected: {//已连接 break; } case HConnectionDisconnected: {//未连接 break; } default: break; } } // 当前登录账号已经被从服务器端删除时会收到该回调 - (void)userAccountDidRemoveFromServer { } //当前登录账号在其它设备登录时会接收到此回调 - (void)userAccountDidLoginFromOtherDevice { } ==== 添加消息监听 ==== //添加消息监控,第二个参数是执行代理方法的队列,默认是主队列 [[HDClient sharedClient].chatManager addDelegate:self delegateQueue:nil]; //移除消息监控 [[HDClient sharedClient].chatManager removeDelegate:self]; - (void)messagesDidReceive:(NSArray *)aMessages{ //收到普通消息,格式: } - (void)cmdMessagesDidReceive:(NSArray *)aCmdMessages{ //收到命令消息,格式:,命令消息不存数据库,一般用来作为系统通知,例如留言评论更新, //会话被客服接入,被转接,被关闭提醒 } - (void)messageStatusDidChange:(HDMessage *)aMessage error:(HDError *)aError{ //消息的状态修改,一般可以用来刷新列表,显示最新的状态 } - (void)messageAttachmentStatusDidChange:(HDMessage *)aMessage error:(HDError *)aError{ //发送消息后,会调用,可以在此刷新列表,显示最新的消息 } ====上传AppStore以及打包ipa注意事项 ==== 为了方便广大开发者开发测试,Demo中提供的framework文件支持x86_64 i386 armv7 arm64平台,上传AppStore(xcode14打包ipa)时需要剔除不需要的CPU架构支持,只剩余arm64平台即可, 【首先进入HelpDesk.xcframework所在目录】 // 移除支持x86_64的二进制文件 直接删除ios-x86_64-simulator文件夹即可 // 移除支持armv7的二进制文件 在进入ios-arm64_armv7的目录 lipo HelpDesk.framework/HelpDesk -remove armv7 -output HelpDesk //替换framwork内部二进制文件[记得备份] mv HelpDesk HelpDesk.framework/HelpDesk //查看剥离后的二进制文件支持的CPU架构,如果显示 arm64,就完成剥离,可上传AppStore lipo -info HelpDesk.framework/HelpDesk 依赖库HyphenateChat.xcframework 【首先进入HyphenateChat.xcframework所在目录】 // 移除支持x86_64的二进制文件 直接删除ios-x86_64-simulator文件夹即可 // 移除支持armv7的二进制文件 在进入ios-arm64_armv7的目录 lipo HyphenateChat.framework/HyphenateChat -remove armv7 -output HyphenateChat //替换framwork内部二进制文件[记得备份] mv HyphenateChat HyphenateChat.framework/HyphenateChat //查看剥离后的二进制文件支持的CPU架构,如果显示 arm64,就完成剥离,可上传AppStore lipo -info HyphenateChat.framework/HyphenateChat ===== 第4步:集成更多业务功能 ===== 完成该步骤可以实现将用户资料传递到客服云,将用户发起的会话直接分配给客服或技能组。 ==== 传访客属性 ==== 传访客属性到客服云,访客属性将显示在“会话”页面的“资料”页签。 管理员模式 >设置 > 功能设置 >允许访客端修改客户信息 要打开,nickName不能为空。 //属性可以缺省 HDVisitorInfo *visitor = [[HDVisitorInfo alloc] init]; visitor.name = @"小明儿"; visitor.qq = @"12345678"; visitor.phone = @"13636362637"; visitor.companyName = @"环信"; visitor.nickName = @"风口上的猪";//不可为空 visitor.email = @"abv@126.com"; visitor.desc = @"环信客服云"; HDMessage *message = [....];//构造相关消息 [message addContent:visitor]; //传访客的属性 注意:如果您有使用视频客服业务,也是支持传递并更新访客信息的,您只需要在音视频的传参加上:在app主页面执行AgoraMessage.newAgoraMessage().setVisitorInfo(visitorInfo);将访客信息在音视频消息处理类里进行设置即可,如果您有任何疑问可以联系我们商务为您做具体解答; ==== 指定某个客服 ==== 当用户点击“联系客服”按钮时,发起的会话直接分配给指定的客服。 客服账号为客服的登录邮箱地址。 HDMessage *message = [....];//构造文字消息 [message addContent:[[HDAgentIdentityInfo alloc] initWithValue:@"客服账号"]]; ==== 指定某个技能组 ==== 当用户点击“联系客服”按钮时,发起的会话直接分配给指定的技能组。 技能组名称须和客服系统设置的技能组名称完全一致,中英文均可。 HDMessage *message = [....];//构造文字消息 [message addContent:[[HDQueueIdentityInfo alloc] initWithValue:@"技能组名称"]]; ==== 开启第二通道获取消息 ==== 第二通道是保证消息投递的第二道保障,即使长连接失效后也会通过轮训的方式获取到最新消息数据。 1、第二通道开启方式: [[HDClient sharedClient].chatManager bindChatWithConversationId:<#会话id#>]; ==== 实时音视频 ==== "商城"Demo包含实时音视频功能,如果不需要实时音视频,只要不导入声网sdk和call文件夹即可 更多实时音视频API请参考[[cs:300visitoraccess:iossdkapi|CEC iOS SDK API]]。 ===== 第5步:集成更多扩展功能 ===== 更多扩展功能(发送轨迹消息、发送订单消息、留言相关功能等),请参考[[cs:300visitoraccess:iossdkapi|CEC iOS SDK API]]。 ===== SDK更新日志 ===== 版本更新信息请查看更新日志。 [[cs:releasenote:iossdk|iOS SDK(访客端)更新日志]]