说明:
本文档介绍如何在 iOS 工程中集成智能客服工作台 SDK。
环境要求
项 | 要求 |
Xcode | 15+ |
Deployment Target | iOS 14.0+ |
Swift | 5.9+ |
CocoaPods | 1.13+ |
链接方式 | 静态链接( use_frameworks! :linkage => :static) |
引入依赖
Podfile
source 'https://github.com/CocoaPods/Specs.git'platform :ios, '14.0'# 业务侧 SDK 与 IM SDK 均为静态二进制,必须使用静态链接use_frameworks! :linkage => :statictarget 'YourApp' dopod 'DeskCustomerUI', '0.1.3'end
初始化
在
AppDelegate 启动期调用一次。Swift
import DeskCustomerUI@UIApplicationMainclass AppDelegate: UIResponder, UIApplicationDelegate {func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {let config = DeskInitConfig(sdkAppID: 1_400_000_000)DeskCustomer.shared.initSDK(config: config)return true}}
Objective-C
#import <DeskCustomerUI/DeskCustomerUI-Swift.h>@implementation AppDelegate- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions {DeskInitConfig *config = [[DeskInitConfig alloc] initWithSDKAppID:1400000000];[DeskCustomer.shared initSDKWithConfig:config];return YES;}@end
登录
Swift
import DeskCustomerUIlet params = DeskLoginParams(userID: "agent_001",token: token,origin: "https://tccc.qcloud.com")DeskCustomer.shared.login(params: params) { error inif let error = error {// 见 §7 错误处理return}let workbench = DeskCustomer.shared.makeWorkbenchViewController()let nav = UINavigationController(rootViewController: workbench)UIApplication.shared.keyWindow?.rootViewController = nav}
Objective-C
#import <DeskCustomerUI/DeskCustomerUI-Swift.h>DeskLoginParams *params = [[DeskLoginParams alloc] initWithUserID:@"agent_001"token: tokenorigin:@"https://tccc.qcloud.com"];[DeskCustomer.shared loginWithParams:paramscompletion:^(NSError * _Nullable error) {if (error) {// 见 §7 错误处理return;}UIViewController *vc = [DeskCustomer.shared makeWorkbenchViewController];UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];UIApplication.sharedApplication.keyWindow.rootViewController = nav;}];
拉起坐席工作台
工作台是一个标准
UIViewController。调用方必须用 UINavigationController 包裹,工作台内部会 push 子页面。Swift
let vc = DeskCustomer.shared.makeWorkbenchViewController()let nav = UINavigationController(rootViewController: vc)present(nav, animated: true)
Objective-C
UIViewController *vc = [DeskCustomer.shared makeWorkbenchViewController];UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];[self presentViewController:nav animated:YES completion:nil];
也可将
nav 设为 window.rootViewController 完成“登录成功 > 切换至工作台”。登出
Swift
DeskCustomer.shared.logout { error in// 已退出}
Objective-C
[DeskCustomer.shared logoutWithCompletion:^(NSError * _Nullable error) {// 已退出}];
错误处理
错误统一为
NSError,domain 为 DeskCustomerErrorDomain(值 "com.desk.customer")。Swift 枚举 | OC 常量 | rawValue | 触发场景 |
.notInitialized | DeskCustomerErrorCodeNotInitialized | -1 | 未调用 initSDK(config:) 就 login |
.invalidParameter | DeskCustomerErrorCodeInvalidParameter | -2 | userID / token / origin 任一为空,或 sdkAppID <= 0 |
.imLoginFailed | DeskCustomerErrorCodeImLoginFailed | -3 | 腾讯云 IM 登录失败; userInfo[@"imCode"] / userInfo[@"imDesc"] 透传 IM 原始信息 |
.workstationLoginFailed | DeskCustomerErrorCodeWorkstationLoginFailed | -4 | 业务侧登录失败(token 过期 / 网络错误等) |
Swift 判断示例
if let nsError = error as NSError?,nsError.domain == DeskCustomerErrorDomain,nsError.code == DeskCustomerErrorCode.workstationLoginFailed.rawValue {showAlert("登录失败,请检查 token 是否过期")}
Objective-C 判断示例
if ([error.domain isEqualToString:DeskCustomerErrorDomain]&& error.code == DeskCustomerErrorCodeWorkstationLoginFailed) {[self showAlert:@"登录失败,请检查 token 是否过期"];}
Info.plist 配置(必需)
聊天页涉及拍照 / 相册 / 麦克风 / 文件选择四类系统能力。iOS 强制要求用途描述键(Usage Description Keys) 由 App 主 target 的
Info.plist 声明——SDK 无法代替接入方注入,也不建议这么做。请在您 App target 的
Info.plist 中至少声明以下两项,否则首次触发对应能力时 App 会立即崩溃:Key | 场景 | 建议文案(简体中文) | 建议文案(English) |
NSCameraUsageDescription | 聊天页更多面板「拍照」发送图片 | 用于聊天页拍摄图片并发送给客户 | Used to take photos in chat and send them to customers |
NSMicrophoneUsageDescription | 聊天页语音消息「按住说话」录音 | 用于聊天页发送语音消息 | Used to record voice messages in chat |
Info.plist(source 视图)示例:
<key>NSCameraUsageDescription</key><string>用于聊天页拍摄图片并发送给客户</string><key>NSMicrophoneUsageDescription</key><string>用于聊天页发送语音消息</string>
无需声明的项
以下三项常见 Key 不需要为本 SDK 声明(除非您的 App 自身另有需要):
NSPhotoLibraryUsageDescription(相册读取权限):SDK 相册选择走 PHPickerViewController(iOS 14+),是 out-of-process 组件,Apple 明确豁免相册权限描述——用户在系统 Picker 里勾了什么,SDK 就只拿到什么。NSPhotoLibraryAddUsageDescription(保存到相册):当前版本 SDK 不涉及“保存到相册”能力。文件选择器:SDK 走
UIDocumentPickerViewController(iCloud Files / 系统文件 App),iOS 未要求 Info.plist 描述。未配置时的表现
未声明
NSCameraUsageDescription:用户点击“拍照”入口的瞬间,App 直接崩溃(SIGABRT),Xcode 控制台会打印 This app has crashed because it attempted to access privacy-sensitive data without a usage description。未声明
NSMicrophoneUsageDescription:用户长按“按住说话”的瞬间,同上直接崩溃。App Store 审核提示
Apple 要求用途描述必须清晰说明用途且面向终端用户。上表建议文案已按此撰写,可直接复制使用;如有本地化需求,请在
InfoPlist.strings 中提供多语言版本。避免使用“用于您的 App 功能”等模糊表述,容易被拒审。本地通知(IM 呼入)
当坐席收到新会话呼入(
imCallin)时,SDK 会自动发出一条本地通知,通知内容包含客户昵称与渠道信息。申请通知权限
SDK 不主动申请权限(避免污染接入方工程),接入方需在合适时机自行申请,例如在
AppDelegate.application(_:didFinishLaunchingWithOptions:) 中:Swift
import UserNotificationsfunc application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {// 申请通知权限let center = UNUserNotificationCenter.current()center.delegate = self // 前台展示所需,见 §9.2center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in// granted = true 时 SDK 才能发出通知}return true}
Objective-C
#import <UserNotifications/UserNotifications.h>- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions {UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];center.delegate = self; // 前台展示所需,见 §9.2[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert |UNAuthorizationOptionSound |UNAuthorizationOptionBadge)completionHandler:^(BOOL granted, NSError *error) {// granted = YES 时 SDK 才能发出通知}];return YES;}
前台展示通知
iOS 默认在 App 处于前台时不展示通知 banner。实现
UNUserNotificationCenterDelegate 的 willPresent 方法可使前台也展示通知:Swift
extension AppDelegate: UNUserNotificationCenterDelegate {func userNotificationCenter(_ center: UNUserNotificationCenter,willPresent notification: UNNotification,withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {if #available(iOS 14.0, *) {completionHandler([.banner, .sound])} else {completionHandler([.alert, .sound])}}}
Objective-C
// AppDelegate.h 中声明协议@interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>// AppDelegate.m 中实现- (void)userNotificationCenter:(UNUserNotificationCenter *)centerwillPresentNotification:(UNNotification *)notificationwithCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {if (@available(iOS 14.0, *)) {completionHandler(UNNotificationPresentationOptionBanner | UNNotificationPresentationOptionSound);} else {completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound);}}
注意:
center.delegate = self 必须在 requestAuthorization 之前设置,否则前台通知不生效。通知行为说明
行为 | 说明 |
触发时机 | 收到 imCallin 事件时立即发出。 |
自动撤销 | 接听、会话结束、超时、登出时自动撤销对应通知。 |
前台 / 后台 | |
无权限时 | 仅打印日志,不触发崩溃,不影响其他功能运行。 |