V5KFClientSDK-iOS
此为V5KF智能客服iOS客户端SDK快速接入文档,包含接入客服系统的基本配置和代码接口,更全面详细的文档可参考这里
1 开发环境准备
- V5KF客服系统账号
如果没有V5KF账号,需要前往官网注册账号。
- 获取应用账号、站点编号
应用账号、站点编号作为SDK连接服务端的身份凭证,可以在V5KF管理后台在“系统接入”->“移动应用APP”配置界面获取。
- 填写对应平台的推送服务器地址(非必需)
为了使您的APP集成本SDK后具有离线消息推送,建议填写您的推送服务器地址,同时也支持第三方推送平台,根据本文档规定填写您的device_token和绑定的用户ID。
- 下载SDK
您可以访问V5KF官网或V5KF Github(推荐)页面下载智能客服SDK,包含了开发包和带UI界面的Demo示例工程,如果您使用CocoaPods导入则无需下载。
- 环境要求
在您集成本智能客服SDK之前,环境要求如下:- 支持的最低iOS版本为8.0。- 支持ARC的Xcode编译器,建议使用最新版本。
2 SDK导入
2.1 Objective-C项目
将V5ClientSDK文件夹复制到您的工程路径下,然后在工程目录结构中,右键选择将文件添加到“工程名”。或者将此文件夹拖入Xcode工程目录结构中,并选择创建分组。
2.2 Swift项目
- 按照上述方法引入
V5ClientSDK
的文件。 - 在Bridging Header头文件中,加入
#import “V5ClientAgent.h”
等相关头文件。注:如何添加Bridging Header。
注:此SDK面向Objective-C开发,可能存在与Swift不兼容的情况
2.3 引入依赖库
V5Client的实现依赖于一些系统框架,在开发应用时,需要在工程中添加这些框架。开发者首先点击项目右边的项目名,然后在项目名右边依次选择 TARGETS -> General -> Linked Frameworks and Libraries,展开 Linked Frameworks and Libraries 后点击展开后的 + 来添加下面的依赖项
- libsqlite3.tbd
- libicucore.tbd
- stdc++.tbd
- AVFoundation.framework
- AudioToolbox.framework
- CFNetwork.framework
- Security.framework
- MediaPlayer.framework
- WebKit.framework
2.4 静态库
注:针对iOS 7+
使用CocoaPods管理依赖库的可以更方便地导入SDK。只需在 Podfile
中加入(此处导入的SDK为静态库,动态库请参考2.5):
platform :ios, '7.0'
pod 'V5ClientSDK'
然后进行pod安装即可:
$ pod install
有新版本更新时:
$ pod update V5ClientSDK
如果运行以上命令,没有找到或找不到最新版本,您可以运行以下命令,更新一下您本地的CocoaPods源列表:
pod repo update
2.5 动态库
注:针对iOS 8+
为满足不断发展的开发需求,本SDK从1.2.7版本开始提供动态库解决方案,命名为V5Client.framework
,并支持使用Cocoapods和Carthage导入,静态库版本也将继续支持。 注:动态库使用时引用头文件方式为#import <V5Client/V5ClientAgent.h>
。
使用CocoaPods导入
platform :ios, '8.0'
use_frameworks!
target 'ClientDemo' do
pod 'V5Client'
end
将target那里的ClientDemo
改为你的target
使用Carthage引入
github "V5KF/V5KFClientSDK-iOS"
然后将Carthage/Build/iOS/V5Client.framework
拖入项目配置的General
->Embedded Binaries
,并选择Copy items if needed
3 Info.plist配置
3.1 ATS
由于 iOS 9 的新功能默认使用 ATS,所有网络请求都需要在安全的连接下(当前 App Store 尚未强制使用 iOS 9 这一新功能),所以一些不兼容的服务需要进行额外的配置。本 SDK 使用到了声讯和图片服务的 webservice 接口,需要在 Info.plist
中添加以下配置
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
关于此功能的详细信息及解决方案,请参考:https://github.com/ChenYilong/iOS9AdaptationTips
注意: 本 SDK 1.1.10 及以上版本已完全兼容 HTTPS
,除非有特殊需求,无需配置 ATS 项 NSAllowsArbitraryLoads
,但仍需配置 NSAllowsArbitraryLoadsInWebContent
。原因:本 SDK 从 1.1.10 版本开始支持 https,SDK 默认会将访问的网络图片(如用户头像)和其他网络请求自动转换为 https 方式访问。如果目标站点不支持 https 而需要 http 访问,可以通过设置 [V5ClientAgent shareClient].config.autoSSL = NO
来取消自动转换 https,并自行配置相应的 ATS 选项。另外,从 1.2.9 版本开始支持 webview 加载网页,网页 URL 无法确保支持 https,因此仍然需要配置 NSAllowsArbitraryLoadsInWebContent
。
3.2 权限
由于 SDK 中使用到相册、相机和录音,需要在 Info.plist 中添加以下内容(以下内容以 XML 格式描述):
<key>NSPhotoLibraryUsageDescription</key>
<string>Choose photo</string>
<key>NSCameraUsageDescription</key>
<string>Take pictures</string>
<key>NSMicrophoneUsageDescription</key>
<string>Record voice</string>
4 SDK接口快速集成
4.1 初始化SDK
将SDK文件添加至工程后,在AppDelegate
中导入“V5ClientAgent.h”
文件,然后在application:willFinishLaunchingWithOptions:
函数中初始化/sdk>。示例代码如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// 初始化SDK
[V5ClientAgent initWithSiteId:@"10000"
appId:@"19cfb0800f474"
exceptionBlock:nil];
return YES;
}
其中siteId
和account
分别可以从V5后台获取到的站点编号和AppID。
4.2 用户信息和参数设置
使用 SDK 提供的 UI 集成,需要在 启动会话界面之前 进行用户信息和参数配置。配置项如下
//需要#import "V5ClientAgent.h"
//获得V5ClientAgent配置对象
V5Config *config = [V5ClientAgent shareClient].config;
//用户信息单次设置即生效,更新用户信息或者切换用户时需调用shouldUpdateUserInfo,设置用户信息前调用
//[config shouldUpdateUserInfo];
//设置用户信息,坐席端可查看
config.nickname = @"test-张三";
config.gender = 1; //性别:0-未知 1-男 2-女
config.avatar = @"头像URL"; //客户头像URL
//openId:用户唯一ID,长度32字节以内,不同的openId消息记录单独保存,可透传到座席端提供给座席插件,替代v1.2.0之前版本的uid(uid不再使用)
//若您是旧版本SDK用户,只是想升级,为兼容旧版,避免客户信息改变可继续使用config.uid,可不用openId
config.openId = @"ios-user-id-for-test";
// 注:openId尽量不要携带特殊字符($&+,/:;=?@%#[]以及空格之类的字符),若包含则会经过urlencode编码,客席插件收到这样的oid后要相应的解码处理(decodeURIComponent)
// 添加自定义用户信息NSDictionary,(仅在开启对话页面前设置生效)
config.userInfo = @{@"商品名称": @"牛仔裤",
@"商品价格": @"¥168.00"};
// [1.3.8新增]设置V5系统内置的客户基本信息,区别于userInfo,这里设置的是V5系统内置字段
// 支持字段:country,province,city,language(上面的nickname,gender,avatar,vip也可在此设置)
config.baseInfo = @{@"country": @"中国",
@"province": @"广东",
@"city": @"深圳",
@"language": @"zh-cn"};
当 nickname
、openId
、avatar
、device_token
等配置项配置完毕,下次需要修改(如 App 内切换了登录账号,修改了客户昵称或头像时)并向座席更新时需要在设置新信息前调用 [config shouldUpdateUserInfo]
,这样才会向服务端更新这几个配置项。同样若想更新站点信息,需要在 onChatActivityConnect
中调用 [[V5ClientAgent shareClient] updateSiteInfo]
。客户信息、站点信息(包含机器人信息和转人工开场白等 V5 后台可设置的信息)的更新存在缓存策略,系统每隔 7 天更新,一般无需处理,需要即时更新时方才调用此处接口。
指定人工客服或分组设置方式:
/*
* 连接建立后才可以调用下面接口,以下是两种转人工情况示例(在onClientViewConnect回调中执行,参考:【README.full.md】5.5 对话界面代理)
*/
// 【转】指定人工客服(调用时立即转),参数: 客服组id,客服id (以下数字仅作为示例,具体ID请前往V5后台查看客服信息)
[[V5ClientAgent shareClient] humanServiceOfGroupId:0 workerId:114052];
// 【指定人工客服】点击转人工按钮或者问题触发转人工时会转到指定人工,参数"0 132916"中两个数字先后对应需要转的客服组ID和客服ID
[[V5ClientAgent shareClient] sendMessage:[[V5ControlMessage alloc] initWithCode:4 argc:2 argv:@"0 114052"]];
4.3 启动会话界面
通过简单地添加一个在线咨询按钮即可使用智能客服客户端功能,在按钮点击事件处理中加入启动会话界面的代码
V5ChatViewController *chatViewController = [V5ClientAgent createChatViewController];
// 不显示底部栏(有底部栏的需加此配置)
chatViewController.hidesBottomBarWhenPushed = YES;
/* 下面为会话界面配置,非必须,可根据需求自定义配置,均有默认值 */
// 会话界面的代理V5ChatViewDelegate,详细的说明可参考[详细文档](./README.full.md)
//chatViewController.delegate = self;
// 设备的ID(也可在config设置deviceToken),有选择推送功能的需要配置
// chatViewController.deviceToken = @"设备的deviceToken";
// 允许并设置消息铃声SystemSoundID
chatViewController.allowSound = YES;
chatViewController.soundID = 1007;
// 允许发送语音
chatViewController.enableVoiceRecord = YES;
// 允许显示头像
chatViewController.showAvatar = YES;
// 头像圆角(0~20之间)
chatViewController.avatarRadius = 6;
// 每次下拉获取历史消息最大数量,默认10
chatViewController.numOfMessagesOnRefresh = 10;
// 开场显示历史消息数量,默认0(显示历史消息>0则无开场白)
chatViewController.numOfMessagesOnOpen = 10;
// 设置会话界面标题
chatViewController.title = @"V5客服"; // 设置标题
// 设置返回按钮标题(默认为前一页面标题)
UIBarButtonItem *myBackItem = [[UIBarButtonItem alloc] init];
myBackItem.title = @"返回";
self.navigationItem.backBarButtonItem = myBackItem;
// 设置开场白方式,启动会话前设置,默认ClientOpenModeDefault
// ClientOpenModeQuestion结合后台机器人培训内容可根据使用场景配置不同需求的开场消息
[chatViewController setClientOpenMode:ClientOpenModeDefault withParam:nil];
// 启动会话界面,使用导航模式推出视图
[self.navigationController pushViewController:(UIViewController *)chatViewController animated:YES];
若开启对话页面非导航模式,则需使用 present 方式打开
@interface ViewController () {
// 添加的导航控制器
UINavigationController *navVC;
}
@end
//......
// 若非导航模式,使用present方式开启,添加导航控制器包裹chatViewController,并加入关闭页面所需的按钮
navVC = [[UINavigationController alloc] initWithRootViewController:chatViewController];
chatViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(closeChat:)];
[self presentViewController:navVC animated:YES completion:nil];
//......
// done按钮点击关闭页面
- (void)closeChat:(id)sender {
[navVC dismissViewControllerAnimated:YES completion:nil];
if ([V5ClientAgent shareClient].isConnected) {
[[V5ClientAgent shareClient] stopClient];
}
}
如果 SDK 使用在 iPad 里,启动会话界面可采用 UIPopoverPresentationController
方式,以及限制横屏状态的处理方式,具体配置如下:
// 页面呈现方式presentType默认PresentType_Push, PopoverViewController下改为PresentType_Popover
chatViewController.presentType = PresentType_Popover;
chatViewController.view.transform = CGAffineTransformMakeScale(0.8, 0.8); //缩小页面内容
//使用UIPopoverPresentationController开启对话
chatViewController.modalPresentationStyle = UIModalPresentationPopover;
chatViewController.preferredContentSize = CGSizeMake(400, 500);
UIPopoverPresentationController* popover = chatViewController.popoverPresentationController;
//设置弹出的基准视图
popover.sourceView = self.button;
popover.sourceRect = self.button.bounds;//打开页面的入口按钮的bunds
popover.delegate = self;
[self presentViewController:chatViewController animated:YES completion:nil];
// 或者使用`UIPopoverController`,iOS9.0以后不再建议使用
// UIPopoverController* popover = [[UIPopoverController alloc] initWithContentViewController:chatViewController];
// [popover setBackgroundColor:[UIColor colorWithRed:235.0/255 green:235.0/255 blue:235.0/255 alpha:1]];
// popover.popoverContentSize = CGSizeMake(chatViewController.view.frame.size.width, chatViewController.view.frame.size.height);
// [popover presentPopoverFromRect:CGRectMake(0,618,1024,50) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
/* 需要手动控制屏幕方向时使用,比如iPad横屏情况 */
// 需要**限制横屏**打开时(UIInterfaceOrientationMaskLandscape),为解决发送图片时选择图库打开页面异常问题,需要在AppDelegate做如下处理
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
if ([V5ClientAgent shareClient].isPhotoLibrary) { //必须,否则打开图库异常
return UIInterfaceOrientationMaskAll;
} else {
return UIInterfaceOrientationMaskLandscape;//or UIInterfaceOrientationMaskAll 允许全部屏幕方向
}
}
4.4 生命周期处理
在使用 UI 集成的 SDK 中,必须在 AppDelegate
中添加以下代码
- (void)applicationDidEnterBackground:(UIApplication *)application {
//退出到后台时,通知 SDK 用户离线
[[V5ClientAgent shareClient] onApplicationDidEnterBackground];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
//移动到前台时,通知 SDK 用户上线并连接
[[V5ClientAgent shareClient] onApplicationWillEnterForeground];
}
此外,不使用客服功能时需要关闭会话服务以节省资源并避免客户离线的状态未更新到座席(已配置离线推送情况下还会影响消息推送)。
以下列举了几种情况下关闭会话的示例:
使用 push 推出页面的,在开启会话界面的前一个界面的
viewDidAppear:
方法中手动调用关闭客服的方法
- (void)viewDidAppear:(BOOL)animated { // 前一 viewController 中
// 不使用客服功能时(在会话 VC 关闭后)退出消息客户端
if ([V5ClientAgent shareClient].isConnected) {
[[V5ClientAgent shareClient] stopClient];
}
}
使用 present 弹出页面的,在关闭页面的 selector 中调用
// done按钮点击关闭页面的selector
- (void)closeChat:(id)sender {
[navVC dismissViewControllerAnimated:YES completion:nil];
if ([V5ClientAgent shareClient].isConnected) {
[[V5ClientAgent shareClient] stopClient];
}
}
以
UIPopoverPresentationController
方式打开的,则需要通过实现UIPopoverPresentationControllerDelegate
的popoverPresentationControllerDidDismissPopover:
来调用[[V5ClientAgent shareClient] stopClient];
- (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController {
// 不使用客服功能时(在会话 VC 关闭后)退出消息客户端
if ([V5ClientAgent shareClient].isConnected) {
[[V5ClientAgent shareClient] stopClient];
}
}
另外,使用
UIPopoverController
或其他方式开启的也同理,需要手动关闭会话。
4.5 第三方输入框兼容问题
使用了 IQKeyboardManager
的 App 在接入本 SDK 后,对话界面弹出软键盘时会有异常,这时只需要关闭 IQKeyboardManager 的功能即可,具体方法如下:
开启会话节面前需要设置 V5ChatViewDelegate
代理:
// 会话界面的代理V5ChatViewDelegate
chatViewController.delegate = self;
实现代理中关于生命周期的方法,分别在 clientViewWillAppear
和 clientViewWillDisappear
添加 IQKeyboardManager
的关闭和开启的代码:
#pragma mark - V5ChatViewDelegate -
/**
* 即将打开会话视图
*/
- (void)clientViewWillAppear {
//取消输入键盘插件
[IQKeyboardManager sharedManager].enable = NO;
[IQKeyboardManager sharedManager].enableAutoToolbar = NO;
}
/**
* 会话视图打开后
*/
- (void)clientViewDidAppear {
}
/**
* 即将关闭会话视图
*/
- (void)clientViewWillDisappear {
//开启输入键盘插件
[IQKeyboardManager sharedManager].enable = YES;
[IQKeyboardManager sharedManager].enableAutoToolbar = YES;
}
/**
* 关闭会话视图后
*/
- (void)clientViewDidDisappear {
}
/**
* 会话连接成功
*/
- (void)onClientViewConnect {
}