CBCentralManager en iOS — qué es, gestión BLE y Core Bluetooth

Autor: IT Sectr Publicado: 2026-07-16 Tiempo de lectura: 11 min

CBCentralManager es la clase central del framework Core Bluetooth en iOS que gestiona el escaneo, la conexión y la interacción con dispositivos periféricos BLE. Core Bluetooth (iOS 5+, 2011) proporciona una abstracción de alto nivel sobre la pila BLE a nivel GATT, ocultando al desarrollador los detalles de Link Layer y HCI. CBCentralManager implementa el rol Central: escanea el aire mediante scanForPeripherals, inicia la conexión mediante connect, descubre servicios mediante discoverServices y gestiona la transferencia de datos. Según la Documentación para Desarrolladores de Apple (2024), CBCentralManager admite hasta 7 conexiones simultáneas a dispositivos BLE en dispositivos con BLE 5.0.

Puntos Clave

  • CBCentralManager es la clase de iOS para gestionar el escaneo BLE, las conexiones y la transferencia de datos en el rol Central.
  • El escaneo se inicia mediante scanForPeripherals con filtrado por UUID de servicio para ahorrar energía.
  • La conexión se realiza mediante connect(peripheral:options:) con seguimiento del estado a través del delegado.
  • iOS admite hasta 7 conexiones BLE simultáneas en dispositivos con BLE 5.0.
  • El escaneo en segundo plano requiere activar bluetooth-central en Background Modes y usar CBCentralManagerScanOptionAllowDuplicatesKey.

¿Qué es CBCentralManager?

CBCentralManager es la clase principal de Core Bluetooth para implementar el rol Central en la arquitectura BLE en iOS. Gestiona todo el ciclo de vida de la conexión BLE: desde el escaneo de dispositivos que se anuncian hasta la transferencia de datos y la desconexión. CBCentralManager funciona de forma asíncrona a través del delegado CBCentralManagerDelegate, notificando a la aplicación sobre eventos en la pila Bluetooth.

La inicialización de CBCentralManager inicia el proceso de restauración de estado: el gestor verifica el estado de Bluetooth en el dispositivo y restaura conexiones anteriores si la aplicación se cerró. El proceso de inicialización puede tomar de 50 a 500 ms dependiendo del estado de Bluetooth. La aplicación debe esperar la llamada centralManagerDidUpdateState antes de iniciar cualquier operación BLE.

La arquitectura de Core Bluetooth se basa en el patrón de Delegación: CBCentralManager delega el manejo de eventos (descubrimiento de dispositivos, conexión, errores) al protocolo CBCentralManagerDelegate. Para trabajar con un Periférico específico, se utiliza el protocolo CBPeripheralDelegate, que notifica sobre servicios descubiertos, características y datos recibidos. Este modelo asíncrono garantiza una interfaz de usuario sin bloqueos.

Estados de CBCentralManager

CBCentralManager pasa por varios estados que determinan si la pila BLE está disponible. El estado se transmite a través del delegado: centralManagerDidUpdateState(_:). El desarrollador debe manejar todos los estados, no solo poweredOn, sino también los casos en que Bluetooth está apagado o no disponible.

EstadoValorAcción del Desarrollador
.poweredOnBluetooth está encendido y listoIniciar escaneo
.poweredOffBluetooth está apagadoMostrar alerta al usuario
.unauthorizedSin permisoSolicitar permiso en Ajustes
.unsupportedEl dispositivo no admite BLEOcultar funciones BLE
.unknownEstado no definidoEsperar la siguiente actualización
.resettingBluetooth se está reiniciandoEsperar recuperación

Estado no autorizado es cada vez más común desde iOS 13+. A partir de esta versión, la aplicación debe tener el permiso NSBluetoothAlwaysUsageDescription en Info.plist. Sin él, el gestor central pasa al estado .unauthorized y el escaneo es imposible. El usuario puede cambiar el permiso en Ajustes > Privacidad > Bluetooth en cualquier momento.

Escaneo de Dispositivos BLE

scanForPeripherals(withServices:options:) es el método principal para iniciar el escaneo. El parámetro withServices acepta un array de UUID de servicio para filtrar: si se pasa nil, se descubrirán todos los dispositivos, lo que aumenta significativamente el consumo de energía. Se recomienda filtrar siempre por los UUID de servicio que necesita la aplicación. Las opciones de escaneo incluyen CBCentralManagerScanOptionAllowDuplicatesKey (notificaciones repetidas sobre el mismo dispositivo).

swift
import CoreBluetooth

class BLEController: NSObject,
    CBCentralManagerDelegate {

    private var centralManager: CBCentralManager!

    override init() {
        super.init()
        centralManager =
            CBCentralManager(
                delegate: self,
                queue: nil
            )
    }

    func startScanning() {
        let serviceUUID =
            CBUUID("180F") // Servicio de Batería

        centralManager.scanForPeripherals(
            withServices: [serviceUUID],
            options: [
                CBCentralManagerScanOptionAllowDuplicatesKey: false
            ]
        )
    }
}

Cuando se descubre un dispositivo, se llama a centralManager(_:didDiscover:advertisementData:rssi:). El parámetro advertisementData contiene el diccionario completo de datos del paquete de anuncio, incluyendo el nombre del dispositivo (CBAdvertisementDataLocalNameKey), los UUID de servicio (CBAdvertisementDataServiceUUIDsKey) y los datos del fabricante (CBAdvertisementDataManufacturerDataKey). RSSI es el nivel de señal en dBm disponible en el momento del descubrimiento.

Conexión a un Periférico

connect(_:options:) es el método para establecer una conexión BLE con un Periférico descubierto. Después de llamar a connect, iOS intenta conectarse al dispositivo. Una conexión exitosa se confirma mediante centralManager(_:didConnect:), un error mediante centralManager(_:didFailToConnect:error:). Las opciones de conexión incluyen CBConnectPeripheralOptionNotifyOnConnectionKey, CBConnectPeripheralOptionNotifyOnDisconnectionKey y CBConnectPeripheralOptionNotifyOnNotificationKey para notificaciones en segundo plano.

swift
// Conectar al dispositivo BLE
func connectToPeripheral(
    _ peripheral: CBPeripheral
) {
    centralManager.connect(peripheral, options: nil)

    // Establecer delegado para Periférico
    peripheral.delegate = self
}

// Delegado: conexión exitosa
func centralManager(
    _ central: CBCentralManager,
    didConnect peripheral: CBPeripheral
) {
    print("Conectado a " +
          "\(peripheral.name ?? "unknown")")

    // Iniciar descubrimiento de servicios
    peripheral.discoverServices(nil)
}

// Delegado: error de conexión
func centralManager(
    _ central: CBCentralManager,
    didFailToConnect peripheral: CBPeripheral,
    error: Error?
) {
    print("Connection failed: 
          \(error?.localizedDescription ?? "")")
}

El tiempo de espera de conexión en iOS es de 30 segundos. Si el dispositivo no ha respondido a la solicitud de conexión en este tiempo, se llama a didFailToConnect. El tiempo de espera se ve afectado por: la distancia al dispositivo, las interferencias y si el dispositivo se está anunciando actualmente. Antes de conectar, asegúrese de que el dispositivo esté en modo de anuncio conectable (ADV_IND, no ADV_NONCONN_IND).

Descubrimiento de Servicios y Características

Después de la conexión, debe descubrir los servicios (discoverServices) y las características (discoverCharacteristics) del Periférico. Este es un paso obligatorio antes de leer o escribir datos. El proceso es asíncrono: discoverServices devuelve resultados mediante peripheral(_:didDiscoverServices:), y discoverCharacteristics mediante peripheral(_:didDiscoverCharacteristicsFor:error:).

Se recomienda pasar un array de UUID relevantes a discoverServices en lugar de nil. El filtrado acelera el descubrimiento y ahorra energía. Si un servicio no se encuentra, iOS informará un array vacío. Después de descubrir las características, puede leer sus valores (readValue), suscribirse a notificaciones (setNotifyValue) o escribir datos (writeValue).

Un matiz importante: el MTU se negocia automáticamente después de la conexión. Para obtener el MTU actual, use peripheral.maximumWriteValueLength(for: .withResponse) o .withoutResponse. En iOS, el MTU máximo es de 512 bytes para dispositivos BLE 5.0. Si necesita transferir datos más grandes que el MTU, implemente la fragmentación a nivel de aplicación.

Escaneo en Segundo Plano y Limitaciones de iOS

El escaneo en segundo plano de dispositivos BLE en iOS requiere configuración especial. Core Bluetooth admite la ejecución en segundo plano, pero con limitaciones significativas. Para trabajar en segundo plano, necesita: activar bluetooth-central en Background Modes en las Capacidades del proyecto, inicializar CBCentralManager con la opción CBCentralManagerOptionRestoreIdentifierKey para la restauración de estado y manejar los eventos del gestor central al pasar a segundo plano.

Limitaciones de BLE en segundo plano en iOS: scanForPeripherals sin filtrado por UUID no funciona en segundo plano. La aplicación debe especificar UUID de servicio concretos para el escaneo. iOS puede retrasar la entrega de eventos BLE indefinidamente. Core Bluetooth reanuda automáticamente el escaneo cuando se descubre un dispositivo coincidente, incluso si la aplicación está en segundo plano. Tiempo de espera para escaneo en segundo plano: iOS puede detener el escaneo después de 10–30 minutos para ahorrar energía.

Restauración de Estado es un mecanismo de Core Bluetooth que permite restaurar conexiones BLE después de un reinicio de la aplicación o del sistema iOS. Para usarlo: especifique CBCentralManagerOptionRestoreIdentifierKey durante la inicialización, implemente centralManager(_:willRestoreState:) en el delegado y restaure la lista de Periféricos conectados desde el diccionario pasado. La Restauración de Estado es una funcionalidad crítica para aplicaciones BLE que funcionan en segundo plano, como rastreadores de fitness o dispositivos médicos.

Manejo de Errores y Recuperación de Conexión

CBCentralManager genera errores en varios escenarios: conexión fallida (didFailToConnect), conexión perdida (didDisconnectPeripheral), característica no disponible para lectura/escritura (error didWriteValue). Todos los errores de Core Bluetooth se devuelven mediante el objeto Error con dominio CBErrorDomain. Los códigos más comunes: CBErrorConnectionTimeout (0x04), CBErrorPeripheralDisconnected (0x07), CBErrorOperationNotSupported (0x0A).

Estrategia de recuperación de conexión: al recibir didDisconnectPeripheral, verifique el código de error. Si el error es CBErrorConnectionTimeout o CBErrorPeripheralDisconnected — programe una reconexión automática en 1–5 segundos. Si el error es CBErrorOperationNotSupported — regístrelo y no intente repetir la operación. Para conexiones críticas (dispositivos médicos), use retroceso exponencial con un intervalo máximo de 60 segundos.

swift
// Manejar desconexión con reconexión automática
func centralManager(
    _ central: CBCentralManager,
    didDisconnectPeripheral peripheral: CBPeripheral,
    error: Error?
) {
    guard let error = error else {
        return // Desconexión esperada
    }

    print("Disconnected: \(error.localizedDescription)")

    // Reconexión automática
    if shouldAutoReconnect {
        DispatchQueue.main.asyncAfter(
            deadline: .now() + reconnectDelay
        ) {
            central.connect(peripheral)
        }
    }
}

Al desarrollar una aplicación BLE robusta en iOS, tenga en cuenta: Core Bluetooth no garantiza la entrega de todos los paquetes con señal débil. Para una transmisión confiable, use writeType .withResponse (escritura confirmada) y suscríbase a notificaciones (setNotifyValue) para recibir datos del Periférico. Mantenga un registro de errores para diagnosticar problemas de conexión en producción.

Preguntas Frecuentes

¿Por qué CBCentralManager no detecta dispositivos?

Verifique el estado del gestor mediante centralManagerDidUpdateState. Asegúrese de que el permiso NSBluetoothAlwaysUsageDescription esté en Info.plist, Bluetooth esté activado en el dispositivo y el periférico se esté anunciando con el tipo correcto (anuncio conectable, no no conectable).

¿Cuántos dispositivos BLE pueden conectarse simultáneamente a iOS?

En dispositivos con BLE 5.0 (iPhone 8 y posteriores) — hasta 7 conexiones simultáneas. En dispositivos más antiguos — hasta 3–5. El número de dispositivos escaneados es ilimitado, pero las conexiones activas tienen un límite estricto establecido por el Controlador Bluetooth.

¿Con qué frecuencia puedo escanear BLE en iOS sin agotar la batería?

Se recomienda escanear con filtrado por UUID y detener el escaneo cuando se encuentre el dispositivo. El escaneo continuo agota la batería: 1 hora de escaneo ininterrumpido consume ~10–15% de la carga del iPhone. Use temporizadores y condiciones para detener el escaneo.

¿Cuál es la diferencia entre CBCentralManager y CBPeripheralManager?

CBCentralManager es para escanear y conectarse a dispositivos BLE externos (rol Central). CBPeripheralManager es para que su dispositivo iOS actúe como periférico BLE (anuncie servicios). Una instancia solo puede estar en un rol.

¿Cómo manejar la pérdida de conexión con un dispositivo BLE?

Implemente centralManager(_:didDisconnectPeripheral:error:). Si el error no es nil — programe una reconexión automática con retroceso exponencial (1 s → 2 s → 4 s → 8 s → máx 60 s). Si el error es nil — el dispositivo se desconectó normalmente (por ejemplo, el usuario presionó un botón en el dispositivo).

Resumen

  • CBCentralManager es la clase principal de Core Bluetooth para gestionar el escaneo BLE, las conexiones y la transferencia de datos en el rol Central en iOS.
  • El escaneo se inicia mediante scanForPeripherals con filtrado opcional por UUID de servicio para reducir el consumo de energía.
  • La conexión se realiza mediante connect, el éxito se confirma con didConnect, el error con didFailToConnect con un tiempo de espera de 30 segundos.
  • Después de la conexión, debe descubrir servicios y características mediante discoverServices y discoverCharacteristics.
  • El escaneo en segundo plano requiere bluetooth-central Background Mode y se admite con limitaciones (filtrado por UUID, posibles retrasos).
  • iOS admite hasta 7 conexiones BLE simultáneas en dispositivos con BLE 5.0, restauración de estado para recuperación después de reinicio.
  • El manejo de errores y la reconexión automática con retroceso exponencial son la base de una aplicación BLE confiable en iOS.

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