En este documento, se explica cómo comenzar a usar el SDK de Headless Mobile para iOS.
El SDK de Headless Mobile para iOS te permite agregar asistencia potenciada por la Plataforma de CCAI directamente a tu propia experiencia integrada en iOS sin usar una IU de la Plataforma de CCAI prediseñada.
En lugar de presentar un widget con la marca de CCAI Platform, haz lo siguiente:
Integra el SDK de CCAI para iOS en tu app.
Crea tus propias pantallas, navegación y diseño visual.
Usa el SDK para hacer lo siguiente:
Iniciar y administrar sesiones de chat y voz
Ofrece opciones de correo electrónico, llamadas programadas y desvío.
Admitir acciones inteligentes, archivos adjuntos y flujos posteriores a la sesión (CSAT, encuestas, agente virtual)
CCAI Platform controla la lógica del centro de contacto (enrutamiento, filas, canales, configuración, informes). Eres propietario de la experiencia completa de la app (IU, flujos y desarrollo de la marca).
Si prefieres una IU configurable prediseñada en lugar de crear la tuya propia, usa el SDK estándar para dispositivos móviles.
Requisitos
Estos son los requisitos para integrar el SDK de Headless Mobile para iOS.
Requisitos de la plataforma iOS
Versión mínima de iOS: iOS 16.6 o versiones posteriores
Lenguaje: Swift
IDE: La versión estable más reciente de Xcode compatible con tu app
Arquitecturas: Son las arquitecturas estándar de iOS compatibles con tu cadena de herramientas de Xcode actual.
Permisos de la app
Debido a que tu app integrada controla la IU de las acciones inteligentes (captura de fotos, grabación de videos o verificación de identidad), debes declarar los permisos de privacidad obligatorios de Apple.
Agrega las siguientes claves a tu Info.plist con una descripción de cómo usa los datos tu app:
NSCameraUsageDescription: Se requiere para que los usuarios tomen y envíen fotos o videos, o para las acciones inteligentes solicitadas por el agente.NSMicrophoneUsageDescription: Se requiere para las llamadas de voz instantáneas y para grabar videos con sonido.NSPhotoLibraryUsageDescription: Se requiere para que los usuarios suban fotos o videos existentes desde la galería de fotos.NSFaceIDUsageDescription: Se requiere si admites acciones inteligentes con verificación biométrica.
Requisitos de la instancia de CCAI Platform
Necesitas acceder a la configuración para desarrolladores de tu instancia de CCAI Platform para obtener los siguientes detalles:
Clave de la empresa
Código secreto de la empresa
URL del host: Es el nombre de host de la plataforma de CCAI (por ejemplo,
your_subdomain.ccaiplatform.com).
Estos valores se usan para lo siguiente:
Clave de la empresa y URL del host: En tu app para iOS, para inicializar el SDK
Código secreto de la empresa: En tu backend, para firmar tokens web JSON (JWT) que se usan para autenticar usuarios.
Notificaciones push
Para las llamadas y ciertas acciones inteligentes, necesitas lo siguiente:
Es la configuración del servicio de notificaciones push de Apple (APNS) para las notificaciones push estándar.
Un certificado de servicios de VoIP para admitir llamadas entrantes y notificaciones específicas relacionadas con las llamadas
Harás lo siguiente:
Configura las credenciales de APNs y VoIP en el portal para desarrolladores de Apple.
Sube los certificados convertidos al portal del administrador de la plataforma de la CCAI en Configuración > Configuración para desarrolladores > App para dispositivos móviles.
Regístrate para recibir notificaciones remotas y VoIP push en tu app.
Reenvía los tokens de dispositivo adecuados al SDK.
En Target > Signing & capabilities, habilita lo siguiente:
Capacidad de notificaciones push
Capacidad de modos en segundo plano con estos elementos marcados:
Voz sobre IP: Se requiere para las notificaciones push de VoIP (llamadas entrantes, acciones inteligentes que usan la RTPC).
Audio, AirPlay y Picture in Picture: Se requieren para que el audio de la llamada de voz continúe cuando la app se ejecuta en segundo plano.
Notificaciones remotas: Se requieren para la entrega push estándar de APNs.
Cómo se adapta el SDK de iOS sin encabezado a tu app
El SDK de Headless Mobile para iOS se puede ver como tres capas:
Plataforma y SDK de CCAI Platform
El SDK interactúa de forma segura con la plataforma de CCAI Platform y proporciona lo siguiente:
Autenticación con tokens web JSON (JWT).
Metadatos de enrutamiento de colas y canales (chat, voz, llamada programada, correo electrónico y vínculos de desvío externos).
Administración del estado de la sesión en tiempo real
Es la canalización de transporte seguro para acciones inteligentes, archivos adjuntos y uso compartido de pantalla.
Lógica de desvío y evaluación de la jerarquía posterior a la sesión
Tu app para iOS (tú te encargas de la IU y la lógica)
Controlas toda la experiencia visual y de navegación:
Puntos de entrada: Por ejemplo, una pestaña de Ayuda o un botón de Comunícate con nosotros.
Menús: Son las filas que se muestran (por ejemplo, Facturación, Asistencia técnica).
IU durante la sesión: Tus burbujas de chat, pantallas de llamadas y controles personalizados.
Qué hace tu app: Llama a las APIs del SDK para iniciar y finalizar sesiones, escucha eventos del SDK y controla la navegación del controlador de vistas.
Configuración del portal de administrador de CCAI Platform
Tus administradores de la plataforma de CCAI configuran las reglas de participación (horario de atención, canales disponibles, umbrales de tiempo de espera y encuestas). El SDK lee esta configuración y la expone a tu app como datos y eventos sin procesar. Tú decides cómo dibujar esa configuración en la pantalla.
Recupera las credenciales de la empresa
Antes de integrar el SDK, obtén las credenciales de tu instancia de la CCAI Platform:
Accede al portal de administrador de CCAI Platform con una cuenta de administrador.
Navega a Configuración > Configuración para desarrolladores.
En Clave y código secreto de la empresa, copia lo siguiente:
Clave de la empresa
Código secreto de la empresa
Anota la URL del host:Es el nombre de host de la plataforma de CCAI (por ejemplo,
your_subdomain.ccaiplatform.com).
Qué usarás:
En tu app para iOS: Clave de la empresa y URL del host
En tu servidor de backend, código secreto de la empresa para firmar JWTs para:
Autenticación del usuario final
Son datos o contexto personalizados opcionales que usa CCAI Platform.
Agrega el SDK a tu app para iOS
El SDK sin interfaz gráfica se compila con una arquitectura modular. Instalas el CCAIKit principal junto con los módulos de funciones específicos que requiere tu app (por ejemplo, CCAIChat o CCAIScreenShare).
Para integrar el SDK de iOS en tu app, sigue la siguiente secuencia de pasos.
Opción A: Swift Package Manager (recomendada)
Agrega lo siguiente a tu archivo
Package.swift:dependencies: [ .package(url: "https://github.com/UJET/ccai-ios-sdk.git", from: "3.3.1") ], targets: [ .target( name: "YourTargetName", dependencies: [ .product(name: "CCAIKit", package: "CCAIKit") ] ) ]Importa
CCAIKiten tu archivoAppDelegate:import CCAIKitSi tu proyecto es de SwiftUI, declara
@UIApplicationDelegateAdaptoren tu structApp:@main struct YourAppName: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate // ... }
Inicializa el SDK sin encabezado
Inicializa el SDK durante el inicio de la app. Debido a la arquitectura modular del SDK, primero debes inicializar el sistema principal de la CCAI y, luego, registrar los módulos de servicio específicos (como el chat o el uso compartido de pantalla).
Inicialización básica
El SDK usa una estructura InitOptions que agrupa toda la configuración requerida:
import CCAIKit
import CCAIChat // If using Chat
import CCAIScreenShare // If using Screen Share
class AppDelegate: NSObject, UIApplicationDelegate, CCAIDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// 1. Configure initialization options
let options = InitOptions(
key: "YOUR_COMPANY_KEY",
urlHost: "your_subdomain.ccaiplatform.com",
delegate: self,
languageCode: "en", // ISO 639 code (defaults to "en")
cacheAuthToken: true // Whether to cache the auth token (defaults to true)
)
// 2. Initialize the core SDK
do {
try CCAI.shared.initialize(options: options)
} catch {
print("Failed to initialize CCAI: \(error.localizedDescription)")
return true
}
// 3. Initialize feature modules
// Chat minimal (no options required)
CCAI.shared.initializeChat()
// Chat with optional configuration
// let chatOptions = ChatOptions(
// delegate: webFormDelegate, // Implement to intercept and render custom web forms within your own UI
// downloadTranscriptVisibility: .hideInPostChat, // Hide the post-chat download affordance
// greeting: "Hello! How can I help you?"
// )
// CCAI.shared.initializeChat(chatOptions)
// Screen Share (optional)
// let screenShareOptions = ScreenShareOptions(
// key: "YOUR_SCREEN_SHARE_KEY",
// domain: "your_domain.com"
// )
// CCAI.shared.initializeScreenShare(screenShareOptions)
return true
}
// ... CCAIDelegate methods (Authentication) go here ...
}
Referencia de configuración de InitOptions
public struct InitOptions {
/// The company key used for authentication
public let key: String
/// The host URL for CCAI platform (for example, "my-unique-instance.uc1.ccaiplatform.com")
public let urlHost: String
/// The preferred language code for localization (defaults to "en")
public var languageCode: String
/// The delegate that receives SDK events and callbacks
public weak var delegate: CCAIDelegate?
/// Whether to cache the authentication token (defaults to true)
public let cacheAuthToken: Bool
}
Servicios disponibles del SDK
Después de la inicialización, puedes acceder a varios servicios a través del singleton CCAI.shared:
let authService = CCAI.shared.authService
let companyService = CCAI.shared.companyService
let queueMenuService = CCAI.shared.queueMenuService
let optionsService = CCAI.shared.optionsService
let languageService = CCAI.shared.languageService
let pushNotificationService = CCAI.shared.pushNotificationService
let endUserService = CCAI.shared.endUserService
let chatService = CCAI.shared.chatService // Only available after initializeChat()
let screenShareService = CCAI.shared.screenShareService // Only available after initializeScreenShare()
let rateService = CCAI.shared.rateService // For CSAT ratings and survey submission
let smartActionService = CCAI.shared.smartActionService // Dedicated service for smart action lifecycle
Recupera la configuración de la empresa
Después de la inicialización, recupera la configuración a nivel de la empresa con companyService. Esto es útil para completar selectores de idioma, mostrar el nombre de la empresa o leer los detalles de contacto de asistencia antes de que el usuario ingrese a una fila.
do {
let company = try await CCAI.shared.companyService?.get()
print("Company: \(company?.displayName ?? "Unknown")")
} catch {
print("Failed to get company info: \(error)")
}
Autenticar usuarios finales
El SDK para dispositivos móviles sin encabezado usa tokens web JSON (JWT) para autenticar a los usuarios y pasar de forma segura información contextual al CRM del agente.
Cómo funciona
El SDK usa un flujo de autenticación asíncrono de dos pasos optimizado:
El SDK determina que debe autenticar al usuario.
Llama a tu método
CCAIDelegate(ccaiShouldAuthenticate()), que es una función asíncrona.Tu app firma un JWT de forma remota en tu servidor de backend con el código secreto de tu empresa.
Luego, tu app pasa el JWT firmado a
CCAI.shared.authService?.authenticate(jwt)para intercambiarlo por un token de autorización.El token de autorización se devuelve al SDK para completar la conexión.
Implementa CCAIDelegate para la autenticación
Tu app debe implementar el protocolo CCAIDelegate. El SDK llama al único método delegado asíncrono cuando necesita autenticación.
Protocolo de CCAIDelegate
public protocol CCAIDelegate: AnyObject {
/// Authenticates the end user and returns an auth token
func ccaiShouldAuthenticate() async -> String?
}
Ejemplo de implementación (Swift)
class AppDelegate: CCAIDelegate {
func ccaiShouldAuthenticate() async -> String? {
// 1. Sign JWT remotely on your backend server
guard let jwt = await signJWTRemotely() else { return nil }
// 2. Authenticate JWT using authService to get an auth token
return try? await CCAI.shared.authService?.authenticate(jwt)
}
}
Ejemplo completo con firma de JWT para referencia y pruebas
class AuthController: CCAIDelegate {
func ccaiShouldAuthenticate() async -> String? {
var jwt = JWT(claims: claims)
// First, sign JWT with company secret (do this on your backend in production)
guard let secret = self.companySecret,
let key = secret.data(using: .utf8) else { return nil }
let signer = JWTSigner.hs384(key: key)
guard let encodedJWT = try? jwt.sign(using: signer) else { return nil }
// Then authenticate JWT using authService to get an auth token
return try? await CCAI.shared.authService?.authenticate(encodedJWT)
}
}
Cómo pasar datos personalizados al CRM
Si deseas pasar datos contextuales al agente (por ejemplo, el SO del dispositivo actual del usuario, su ubicación o el nivel de su cuenta), tu backend debe insertar un objeto custom_data en la carga útil del JWT antes de firmarlo.
Cada fragmento de datos personalizados debe tener el formato de un objeto JSON que contenga un label (lo que ve el agente), un value y un type.
Tipos de datos admitidos
string: Texto estándar (por ejemplo, "iPhone 14 Pro").number: Números enteros o de punto flotante (por ejemplo, 1234 o 99.99)date: Es una marca de tiempo Unix en UTC de 13 dígitos que incluye milisegundos (por ejemplo, 1537399655992).url: Es el formato estándar de URL HTTP/HTTPS.boolean: Es un valor estándar verdadero o falso.
Claves de CRM reservadas
CCAI Platform admite claves reservadas específicas que activan comportamientos integrados en la plataforma, como marcar a un usuario como VIP o advertir a un agente sobre un actor malicioso. Deben tener el formato de tipos booleanos y solo se aceptan si la carga útil se firma con el método JWT seguro.
reserved_verified_customer: Indica si tus sistemas internos autenticaron correctamente a un cliente.reserved_bad_actor: Marca al usuario para el agente como un posible spammer o una cuenta fraudulenta.reserved_repeat_customer: Indica si este cliente se comunicó con el equipo de asistencia al cliente con frecuencia recientemente.
Ejemplo de carga útil con claves reservadas
{
"iat": 1537399656,
"exp": 1537400256,
"custom_data": {
"reserved_verified_customer": {
"label": "Verified Customer",
"value": true,
"type": "boolean"
},
"reserved_bad_actor": {
"label": "Bad Actor",
"value": false,
"type": "boolean"
},
"reserved_repeat_customer": {
"label": "Repeat Customer",
"value": false,
"type": "boolean"
}
}
}
Administra tokens de autenticación
El SDK también proporciona métodos para actualizar o borrar manualmente el token de autenticación almacenado en caché:
// Set a new auth token
CCAI.shared.authService?.updateAuthToken("new_auth_token")
// Clear the current token (for example, on user logout)
CCAI.shared.authService?.updateAuthToken(nil)
Esquema de carga útil del JWT de datos personalizados
Cuando tu backend cree la carga útil final que se firmará con el código secreto de tu empresa, deberá seguir estrictamente este esquema. Ten en cuenta las marcas de tiempo obligatorias iat (fecha de emisión) y exp (fecha de vencimiento).
{
"iat": 1537399656,
"exp": 1537400256,
"custom_data": {
"os_version": {
"label": "OS Version",
"value": "16.4",
"type": "string"
},
"membership_tier": {
"label": "Membership Tier",
"value": "Platinum",
"type": "string"
},
"ssn_last_four": {
"label": "SSN",
"value": "1234",
"type": "string",
"invisible_to_agent": true
},
"reserved_verified_customer": {
"label": "Verified Customer",
"value": true,
"type": "boolean"
}
}
}
Habilita las notificaciones push
El SDK usa notificaciones push para lo siguiente:
Llamadas entrantes
Determinadas acciones inteligentes y eventos relacionados con llamadas
Mantener el estado cuando la app está en segundo plano
Configura certificados
La plataforma de CCAI requiere que se guarden dos tipos diferentes de certificados push de Apple en el portal de administrador de la plataforma de CCAI:
Un certificado SSL del servicio de notificaciones push de Apple (APNs), que se usa para las notificaciones push remotas estándar.
Un certificado de servicios de VoIP, que se usa para las notificaciones de llamadas entrantes y ciertas acciones inteligentes relacionadas con las llamadas
Ambos certificados se crean en el portal de Apple Developer, se convierten al formato PEM y, luego, se suben al portal del administrador de la plataforma de CCAI.
Crea un certificado SSL de APNs
Sigue estos pasos, basados en la guía oficial de Apple Establishing a Certificate-Based Connection to APNs, para crear un certificado SSL de APNs.
Accede a developer.apple.com y navega a Certificates, Identifiers & Profiles.
Selecciona el botón + para crear un certificado nuevo.
En Services, selecciona Apple Push Notification service SSL (Sandbox & Production).
Elige el ID de la app que coincida con el identificador del paquete de tu aplicación y, luego, selecciona Continuar.
Sube una solicitud de firma de certificado (CSR) generada desde Acceso a Llaveros en tu Mac:
Abre Acceso a Llaveros > Asistente de Certificados > Solicitar un certificado a una autoridad de certificación…
Ingresa tu dirección de correo electrónico, deja vacío el campo Dirección de correo electrónico de la CA, selecciona Guardado en el disco y, luego, Continuar.
Selecciona Continuar y, luego, Descargar el archivo
.cergenerado.Haz doble clic en el archivo
.cerpara instalarlo en tu Llavero.En Acceso a Llaveros, busca el certificado instalado, haz clic con el botón derecho en él y selecciona Exportar… para guardarlo como un archivo
.p12. Se te solicitará que establezcas una contraseña de exportación.Convierte el archivo
.p12al formato PEM conopenssl:# Extract the certificate openssl pkcs12 -in apns_certificate.p12 -out apns_cert.pem -clcerts -nokeys # Extract the private key openssl pkcs12 -in apns_certificate.p12 -out apns_key.pem -nocerts -nodes # (Optional) Combine into a single PEM file cat apns_cert.pem apns_key.pem > apns_combined.pem
Crea un certificado de servicios de VoIP
Los certificados de servicios de VoIP permiten que tu app reciba notificaciones push de alta prioridad a través del framework de PushKit de Apple, que puede activar tu app desde un estado finalizado para controlar las llamadas entrantes. Para conocer los pasos oficiales más recientes, consulta Crea certificados de servicios de VoIP en la documentación para desarrolladores de Apple.
Accede a developer.apple.com y navega a Certificates, Identifiers & Profiles.
Selecciona el botón + para crear un certificado nuevo.
En Servicios, selecciona Certificado de servicios de VoIP.
Elige el ID de la app que coincida con el identificador del paquete de tu aplicación y, luego, selecciona Continuar.
Sube la misma solicitud de firma de certificado (CSR) que generaste para tu certificado SSL de APNs (o crea una nueva).
Selecciona Continuar y, luego, Descargar el archivo
.cergenerado.Haz doble clic en el archivo
.cerpara instalarlo en tu Llavero.En Acceso a Llavero, busca el certificado de servicios de VoIP instalado, haz clic con el botón derecho en él y selecciona Exportar… para guardarlo como un archivo
.p12.Convierte el archivo
.p12al formato PEM conopenssl:# Extract the certificate openssl pkcs12 -in voip_certificate.p12 -out voip_cert.pem -clcerts -nokeys # Extract the private key openssl pkcs12 -in voip_certificate.p12 -out voip_key.pem -nocerts -nodes # (Optional) Combine into a single PEM file cat voip_cert.pem voip_key.pem > voip_combined.pem
Sube certificados al portal de administrador de CCAI Platform
Accede al portal de administración de CCAI Platform.
Navega a Configuración > Configuración para desarrolladores > App para dispositivos móviles.
Sube el certificado PEM de APNs.
Sube el certificado PEM de VoIP.
Cómo solicitar permisos de notificaciones push
El SDK proporciona un método de conveniencia para solicitar la autorización de notificaciones push (solo para iOS):
let options: UNAuthorizationOptions = [.alert, .sound]
try await CCAI.shared.pushNotificationService?.registerForPushNotifications(
options: options
) { granted in
if granted {
print("Push notifications granted")
} else {
print("Push notifications denied")
}
}
Regístrate para habilitar las notificaciones remotas
Implementa los delegados de notificaciones push en tu AppDelegate. El SDK proporciona pushNotificationService para reenviar tokens:
import CCAIKit
class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
CCAI.shared.pushNotificationService?.updatePushToken(
data: deviceToken,
type: .apns
)
}
func application(
_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error
) {
CCAI.shared.pushNotificationService?.updatePushToken(
data: nil,
type: .apns
)
}
}
Asegúrate de habilitar también Capabilities > Push notifications y Background modes para las notificaciones remotas desde la pestaña Target > Signing & capabilities en Xcode.
Cómo controlar las notificaciones push entrantes
Cuando recibas una carga útil de envío, reenvíala al SDK para que la procese:
func application(
_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
) {
// Let the SDK determine if this push relates to an incoming call,
// session update, or another internal event
CCAI.shared.pushNotificationService?.handlePushNotification(userInfo)
completionHandler(.newData)
}
El SDK determina si la notificación push se relaciona con una llamada entrante, una actualización de sesión o algún otro evento interno, y la controla según corresponda.
Regístrate para recibir notificaciones push de VoIP
Para las llamadas entrantes y ciertas acciones inteligentes basadas en la RTCP, el SDK requiere un token push de VoIP además del token estándar de APNs. Las notificaciones push de VoIP se entregan con alta prioridad y pueden activar tu app desde un estado finalizado.
Importa PushKit y crea un PKPushRegistry en el didFinishLaunchingWithOptions de tu AppDelegate
import PushKit
class AppDelegate: NSObject, UIApplicationDelegate, PKPushRegistryDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// ... SDK initialization ...
// Register for VoIP push notifications
let voipRegistry = PKPushRegistry(queue: DispatchQueue.main)
voipRegistry.delegate = self
voipRegistry.desiredPushTypes = [.voIP]
return true
}
}
Implementa los métodos de PKPushRegistryDelegate para reenviar tokens y cargas útiles de VoIP al SDK
// MARK: - PKPushRegistryDelegate
func pushRegistry(
_ registry: PKPushRegistry,
didUpdate credentials: PKPushCredentials,
for type: PKPushType
) {
// Forward the VoIP token to the SDK
CCAI.shared.pushNotificationService?.updatePushToken(
data: credentials.token,
type: .voip
)
}
func pushRegistry(
_ registry: PKPushRegistry,
didInvalidatePushTokenFor type: PKPushType
) {
// Clear the VoIP token
CCAI.shared.pushNotificationService?.updatePushToken(
data: nil,
type: .voip
)
}
func pushRegistry(
_ registry: PKPushRegistry,
didReceiveIncomingPushWith payload: PKPushPayload,
for type: PKPushType,
completion: @escaping () -> Void
) {
guard type == .voIP else {
completion()
return
}
// Forward the VoIP payload to the SDK using the `handleVoIPPush`
// extension on `CCAI` (defined in the `CCAICall` module). The SDK
// takes ownership of the call lifecycle; invoke PushKit's completion
// handler in the trailing closure after the SDK has accepted the
// payload.
CCAI.shared.handleVoIPPush(payload: payload.dictionaryPayload) { completion() }
}