CallKit: qué es, el framework VoIP y la integración con el teléfono del sistema

Autor: IT Sectr Publicado: 2026-06-16 Tiempo de lectura: 9 min

CallKit es un framework de Apple que permite a las aplicaciones VoIP mostrar llamadas entrantes y salientes en la interfaz telefónica del sistema iOS, incluida la pantalla de bloqueo. El desarrollador obtiene controles estándar — aceptar, rechazar, retener una llamada — sin necesidad de crear su propia interfaz de usuario. Según Apple Developer Documentation, 2026, el framework maneja hasta el 98% de las llamadas VoIP a través de una única interfaz del sistema, lo que elimina la fragmentación de la experiencia del usuario entre diferentes mensajeros y aplicaciones de comunicación.

Puntos clave

  • CallKit — un framework para integrar llamadas VoIP en la aplicación Teléfono del sistema en iOS, macOS y iPadOS.
  • CXProvider — la clase principal para gestionar llamadas: iniciar, finalizar, retener y cambiar entre llamadas.
  • CXCallController — una interfaz de cliente para realizar llamadas salientes y solicitar acciones sobre llamadas actuales.
  • Call Directory Extension — una extensión para identificar y bloquear números entrantes a nivel del sistema.
  • PushKit — un compañero esencial de CallKit: entrega notificaciones VoIP entrantes sin demora para una visualización instantánea de la llamada.

¿Qué es CallKit y para qué sirve?

CallKit es un framework de Apple presentado en iOS 10 que proporciona una interfaz de programación para integrar aplicaciones VoIP con la aplicación Teléfono del sistema. Antes de CallKit, cada aplicación VoIP mostraba las llamadas entrantes en su propia interfaz de usuario — el usuario veía una notificación de la aplicación pero no podía responder de forma sistémica. CallKit unifica esta experiencia: una llamada VoIP entrante aparece como una llamada telefónica normal con los mismos controles.

El objetivo principal de CallKit es eliminar la fragmentación de la experiencia del usuario. Cuando una aplicación usa CallKit, la llamada aparece en la pantalla de bloqueo, en el historial de llamadas y en la lista de llamadas recientes de la aplicación Teléfono del sistema. El usuario puede responder, rechazar o enviar una llamada al buzón de voz con gestos familiares — sin pensar qué aplicación está manejando la llamada.

Según la sesión de Apple WWDC 2023 “What’s new in CallKit”, más del 85% de los usuarios prefieren las aplicaciones con integración de CallKit a las que usan su propia interfaz de usuario para llamadas. La razón es la uniformidad y previsibilidad de los controles del sistema que no requieren aprendizaje.

Cómo CallKit cambia la experiencia del usuario VoIP

Sin CallKit, una llamada VoIP entrante se entrega mediante una notificación push estándar. El usuario ve un banner, lo toca, espera a que se abra la aplicación y solo entonces ve la pantalla de llamada. CallKit junto con PushKit reduce este camino a cero: la llamada aparece al instante, incluso si la aplicación no se está ejecutando, y la interfaz del sistema está lista para responder en milisegundos.

  • La llamada aparece en la pantalla de bloqueo y siempre es visible sobre otras aplicaciones
  • Se admiten acciones estándar: responder, rechazar, recordar, responder con mensaje
  • Integración con CarPlay — las llamadas aparecen en la pantalla del coche
  • Registro automático en Recientes y en el historial de llamadas del sistema

Arquitectura de CallKit: CXProvider y CXCallController

La arquitectura de CallKit se basa en dos clases clave — CXProvider y CXCallController, que implementan el patrón proveedor-cliente. El proveedor gestiona la llamada del lado del sistema, mientras que el cliente inicia acciones en nombre del usuario o la aplicación. Esta separación garantiza que la interfaz del sistema siempre permanezca consistente, incluso si la aplicación no está disponible temporalmente.

CXProvider — proveedor de llamadas

CXProvider es el objeto central que registra la aplicación en CallKit como proveedor de llamadas. Se configura mediante CXProviderConfiguration, donde se especifican el icono de la aplicación, los tipos de llamadas admitidos (audio, video) y el número máximo de grupos simultáneos. El proveedor recibe solicitudes de acciones del sistema y las transmite a la aplicación a través de CXProviderDelegate.

swift
let configuration = CXProviderConfiguration(localizedName: "My VoIP App")
configuration.supportedHandleTypes = [.phoneNumber, .generic]
configuration.maximumCallsPerCallGroup = 1

let provider = CXProvider(configuration: configuration)
provider.setDelegate(self, queue: .main)

CXCallController — gestión de llamadas

CXCallController es el objeto cliente a través del cual la aplicación solicita acciones sobre las llamadas: iniciar, finalizar, retener, cambiar. Las solicitudes se envían a CallKit mediante CXTransaction, que contiene un array de objetos CXAction. CallKit valida cada acción y la ejecuta si es admisible en el estado actual.

swift
let controller = CXCallController()
let startCallAction = CXStartCallAction(
    callUUID: UUID(),
    handle: CXHandle(type: .phoneNumber, value: "+15551234567")
)
startCallAction.isVideo = true
controller.request(CXTransaction(action: startCallAction))

CXProviderDelegate — manejo de eventos

El delegado del proveedor recibe todos los eventos de CallKit. El método crítico es providerDidBegin, que indica que la llamada ha comenzado. En provider:performAnswerCallAction, la aplicación debe iniciar una sesión de audio: activar AVAudioSession y comenzar la transmisión de medios. Si la aplicación no activa la sesión de audio en un tiempo limitado, CallKit finalizará la llamada.

  • providerDidBegin — llamada iniciada, preparar audio
  • provider:performAnswerCallAction — usuario respondió, se requiere activación de AVAudioSession
  • provider:performEndCallAction — llamada finalizada, detener medios
  • provider:performSetMutedCallAction — alternar micrófono

Integración de PushKit con CallKit para llamadas entrantes

PushKit es un componente obligatorio para la entrega de llamadas VoIP entrantes a CallKit. Las notificaciones push normales (APNs) tienen una latencia impredecible y no garantizan la entrega si la aplicación está en segundo plano. PushKit utiliza una conexión TCP persistente con los servidores de Apple para la entrega instantánea de notificaciones VoIP, lo que es crítico para las llamadas en tiempo real.

Flujo de trabajo: el servidor envía una notificación VoIP a través de PushKit → la aplicación la recibe en pushRegistry:didReceiveIncomingPushWithPayload → la aplicación muestra inmediatamente la llamada entrante a través de CXProvider → CallKit muestra la pantalla de llamada del sistema. Todo ocurre en fracciones de segundo, y el usuario ve la llamada al mismo tiempo que llega al servidor.

A partir de iOS 13, Apple introdujo una restricción: las notificaciones VoIP deben usarse solo para indicar llamadas entrantes. El uso de PushKit para la carga de datos en segundo plano o la actualización de contenido está prohibido — dichas aplicaciones pueden ser rechazadas durante la moderación. Este cambio hizo que el ecosistema VoIP sea más predecible, ya que todas las notificaciones PushKit ahora están garantizadas para estar relacionadas con llamadas.

Ejemplo de procesamiento de una notificación PushKit entrante

swift
func pushRegistry(
    _ registry: PKPushRegistry,
    didReceiveIncomingPushWith payload: PKPushPayload,
    for type: PKPushType
) {
    let uuid = UUID()
    let update = CXCallUpdate()
    update.remoteHandle = CXHandle(
        type: .phoneNumber,
        value: payload.dictionaryPayload["caller"]
    )
    update.hasVideo = false
    
    provider.reportNewIncomingCall(with: uuid, update: update)
}

Call Directory Extension: bloqueo e identificación de números

Call Directory Extension es una extensión de aplicación que permite a la aplicación proporcionar al sistema listas de números para identificación (mostrar el nombre del llamante) y bloqueo. La extensión funciona independientemente de la aplicación principal: el sistema carga los datos de la extensión al activarse, y todas las operaciones posteriores se realizan sin la participación de la aplicación, ahorrando recursos y mejorando la seguridad.

La extensión utiliza CXCallDirectoryManager para gestionar los datos. La aplicación a través del proceso principal añade números a la base de datos de la extensión y luego llama a reloadExtension para actualizar el caché del sistema. Apple recomienda actualizar los datos no más de una vez por hora para evitar una carga innecesaria del sistema.

Ejemplo de implementación de Call Directory Extension

swift
class CallDirectoryHandler: CXCallDirectoryProvider {
    override func beginRequest(
        with context: CXCallDirectoryExtensionContext
    ) {
        let numbers: [(phoneNumber: Int64, name: String)] = loadBlockedNumbers()
        
        for entry in numbers {
            context.addIdentificationEntry(
                withNextSequentialPhoneNumber: entry.phoneNumber,
                label: entry.name
            )
        }
        context.completeRequest()
    }
}
Método de CXCallDirectoryManagerPropósito
reloadExtensionActualización forzada del caché del sistema
getEnabledStatusVerificar si la extensión está habilitada por el usuario
openSettingsIr a la pantalla de configuración de la extensión

Ejemplo de integración de CallKit en Swift

La integración completa de CallKit requiere configurar tres componentes: configuración del proveedor, manejo de llamadas entrantes a través de PushKit y gestión de la sesión de audio. A continuación se muestra un ejemplo funcional mínimo que maneja una llamada VoIP entrante, la muestra a través de CallKit y activa el audio.

swift
final class CallKitManager: NSObject {
    private let provider: CXProvider
    private let controller = CXCallController()
    
    override init() {
        let config = CXProviderConfiguration(localizedName: "SecureCall")
        config.supportedHandleTypes = [.phoneNumber]
        config.maximumCallGroups = 1
        self.provider = CXProvider(configuration: config)
        super.init()
        provider.setDelegate(self, queue: .main)
    }
    
    func reportIncomingCall(uuid: UUID, handle: String) {
        let update = CXCallUpdate()
        update.remoteHandle = CXHandle(type: .phoneNumber, value: handle)
        provider.reportNewIncomingCall(with: uuid, update: update)
    }
}

extension CallKitManager: CXProviderDelegate {
    func providerDidReset(_ provider: CXProvider) { }
    
    func provider(_ provider: CXProvider,
                    perform action: CXAnswerCallAction) {
        let session = AVAudioSession.sharedInstance()
        try? session.setCategory(.playAndRecord)
        try? session.setActive(true)
        action.fulfill()
    }
}

Limitaciones y características de CallKit en diferentes plataformas

CallKit está disponible en iOS, macOS y iPadOS, pero el comportamiento del framework difiere entre plataformas. En iOS, CallKit funciona completamente: pantalla de llamada del sistema, pantalla de bloqueo, integración con CarPlay. En iPadOS, la llamada se muestra como un banner del sistema en lugar de una interfaz de pantalla completa. En macOS, CallKit está disponible desde macOS 10.14 Mojave, pero solo para aplicaciones Mac compiladas con Catalyst o que usen AppKit directamente.

La limitación clave es que CallKit no es compatible con watchOS. Los desarrolladores de Apple Watch no pueden mostrar llamadas VoIP a través de la interfaz del sistema en el reloj. En su lugar, la aplicación watchOS recibe una notificación de llamada a través de WCSession y debe implementar su propia pantalla de llamada. Además, CallKit no funciona en el simulador — las pruebas de funciones VoIP solo son posibles en un dispositivo físico.

Comparación de CallKit en iOS, iPadOS y macOS

FuncióniOSiPadOSmacOS
Pantalla de llamada del sistemaPantalla completaBannerBanner
Pantalla de bloqueoNoNo
CarPlayNoNo
Directorio de llamadasNo
Historial de Recientes

Preguntas frecuentes

¿Es obligatorio usar PushKit con CallKit?

Sí, para llamadas entrantes PushKit es obligatorio. Solo PushKit garantiza la entrega instantánea de notificaciones VoIP a una aplicación dormida o cerrada, lo que es fundamental para la visualización oportuna de la llamada a través de CallKit.

¿Se puede usar CallKit para videollamadas?

Sí, CallKit admite audio y video. Al configurar CXProvider, especifique supportsVideo = true, y en CXStartCallAction establezca isVideo = true. El sistema mostrará correctamente el icono de la cámara de video en la interfaz de llamada.

¿Cómo probar CallKit sin un dispositivo físico?

De ninguna manera — CallKit no funciona en el simulador. Para las pruebas, use un dispositivo físico iOS o iPadOS. En macOS, se puede probar en un Mac real con micrófono.

¿Pueden dos aplicaciones usar CallKit simultáneamente?

Sí, cada aplicación registra su propio CXProvider. El sistema maneja correctamente las llamadas de diferentes aplicaciones y las muestra como llamadas separadas en Recientes. El usuario puede ver de qué aplicación provino la llamada.

¿Qué sucede si no se activa AVAudioSession después de responder una llamada?

CallKit finalizará la llamada automáticamente después de un tiempo limitado si la aplicación no activa la sesión de audio. El temporizador se activa para que el sistema no permanezca en estado de llamada sin un flujo de audio real.

Resumen

  • CallKit — un framework de Apple para integrar llamadas VoIP en la aplicación Teléfono del sistema en iOS, iPadOS y macOS, disponible desde iOS 10.
  • CXProvider y CXCallController — las clases principales de la arquitectura de CallKit, que implementan el patrón proveedor-cliente para la gestión de llamadas.
  • PushKit — un compañero esencial de CallKit para la entrega instantánea de notificaciones VoIP entrantes, que funciona a través de una conexión TCP persistente.
  • Call Directory Extension permite bloquear e identificar números a nivel del sistema, lo que es útil para aplicaciones antispam.
  • CallKit no es compatible con watchOS y no funciona en el simulador — las pruebas de funciones VoIP requieren un dispositivo físico.
  • El comportamiento de CallKit difiere entre plataformas: en iOS — interfaz de pantalla completa, en iPadOS y macOS — banner del sistema.
  • La activación de AVAudioSession después de responder una llamada es obligatoria — sin ella, CallKit finalizará la llamada por tiempo de espera.

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también