CBCentralManager în iOS — ce este, gestionare BLE și Core Bluetooth

Autor: IT Sectr Publicat: 2026-07-16 Timp de citire: 11 min

CBCentralManager — este clasa centrală a framework-ului Core Bluetooth în iOS, care gestionează scanarea, conectarea și interacțiunea cu dispozitivele periferice BLE. Core Bluetooth (iOS 5+, 2011) oferă o abstractizare de nivel înalt peste stiva BLE la nivel GATT, ascunzând dezvoltatorului detaliile Link Layer și HCI. CBCentralManager îndeplinește rolul Central: scanează eterul prin scanForPeripherals, inițioază conexiunea prin connect, descoperă servicii prin discoverServices și gestionează transferul de date. Conform Apple Developer Documentation (2024), CBCentralManager suportă până la 7 conexiuni BLE simultane pe dispozitive cu BLE 5.0.

Puncte cheie

  • CBCentralManager — clasa iOS pentru gestionarea scanării BLE, conectării și transferului de date în rolul Central.
  • Scanarea se pornește prin scanForPeripherals cu filtrare după UUID-urile serviciilor pentru economisirea energiei.
  • Conectarea se realizează prin connect(peripheral:options:) cu urmărirea stării prin delegat.
  • iOS suportă până la 7 conexiuni BLE simultane pe dispozitive cu BLE 5.0.
  • Scanarea în fundal necesită activarea bluetooth-central în Background Modes și utilizarea CBCentralManagerScanOptionAllowDuplicatesKey.

Ce este CBCentralManager?

CBCentralManager — este clasa principală Core Bluetooth pentru implementarea rolului Central în arhitectura BLE pe iOS. Gestionează înntregul ciclu de viață al conexiunii BLE: de la scanarea dispozitivelor care se publicită până la transferul de date și deconectare. CBCentralManager lucrează asincron prin delegatul CBCentralManagerDelegate, notificând aplicația despre evenimentele din stiva Bluetooth.

Inițializarea CBCentralManager pornește procesul de state restoration: managerul verifică starea Bluetooth pe dispozitiv și restabilește conexiunile anterioare dacă aplicația a fost închisă. Procesul de inițializare poate dura între 50 și 500 ms în funcție de starea Bluetooth. Aplicația trebuie să aștepte apelul centralManagerDidUpdateState înainte de a îNCEpe orice operațiuni BLE.

Arhitectura Core Bluetooth este construită pe modelul Delegation: CBCentralManager delegă procesarea evenimentelor (descoperirea dispozitivelor, conectare, erori) protocolului CBCentralManagerDelegate. Pentru lucrul cu un Peripheral specific se utilizează protocolul CBPeripheralDelegate, care notifică despre descoperirea serviciilor, caracteristicilor și primirea datelor. Acest model asincron asigură funcționarea neblocantă a UI-ului.

Stările CBCentralManager

CBCentralManager trece prin mai multe stări care determină dacă stiva BLE este disponibilă pentru lucru. Starea este transmisă prin delegat: centralManagerDidUpdateState(_:). Dezvoltatorul trebuie să gestioneze toate stările — nu doar poweredOn, ci și cazurile când Bluetooth este oprit sau indisponibil.

StareSemnificațieAcțiunea dezvoltatorului
.poweredOnBluetooth este pornit și pregătitÎncepe scanarea
.poweredOffBluetooth este opritAfișează un alert utilizatorului
.unauthorizedFără permisiuneSolicită permisiunea în Setări
.unsupportedDispozitivul nu suportă BLEAscunde funcțiile BLE
.unknownStare nedefinităAșteaptă următoarea actualizare
.resettingBluetooth se reporneșteAșteaptă restabilirea

Unauthorized state devine din ce în ce mai frecventă începând cu iOS 13+. De la această versiune, aplicația trebuie să aibă permisiunea NSBluetoothAlwaysUsageDescription în Info.plist. Fără ea, managerul central trece în starea .unauthorized, iar scanarea este imposibilă. Utilizatorul poate modifica permisiunea în orice moment în Settings > Privacy > Bluetooth.

Scanarea dispozitivelor BLE

scanForPeripherals(withServices:options:) — metoda principală pentru pornirea scanării. Parametrul withServices primește un array de UUID-uri ale serviciilor pentru filtrare: dacă se trimite nil, vor fi descoperite toate dispozitivele, ceea ce crește semnificativ consumul de energie. Se recomandă să filtrați întotdeauna după UUID-urile serviciilor de care are nevoie aplicația. Opțiunile de scanare includ CBCentralManagerScanOptionAllowDuplicatesKey (notificări repetate despre același dispozitiv).

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") // Serviciul Baterie

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

La descoperirea unui dispozitiv, este apelat centralManager(_:didDiscover:advertisementData:rssi:). Parametrul advertisementData conține un dicționar complet al datelor pachetului de publicitate, inclusiv numele dispozitivului (CBAdvertisementDataLocalNameKey), UUID-urile serviciilor (CBAdvertisementDataServiceUUIDsKey) și datele producătorului (CBAdvertisementDataManufacturerDataKey). RSSI — nivelul semnalului în dBm, disponibil în momentul descoperirii.

Conectarea la Peripheral

connect(_:options:) — metoda pentru stabilirea conexiunii BLE cu Peripheral-ul descoperit. După apelul connect, iOS încearcă să se conecteze la dispozitiv. Conexiunea reușită este confirmată prin apelul centralManager(_:didConnect:), iar eroarea prin centralManager(_:didFailToConnect:error:). Opțiunile de conectare includ CBConnectPeripheralOptionNotifyOnConnectionKey, CBConnectPeripheralOptionNotifyOnDisconnectionKey și CBConnectPeripheralOptionNotifyOnNotificationKey pentru notificări în fundal.

swift
// Conectare la dispozitiv BLE
func connectToPeripheral(
    _ peripheral: CBPeripheral
) {
    centralManager.connect(peripheral, options: nil)

    // Setează delegat pentru Peripheral
    peripheral.delegate = self
}

// Delegat: conexiune reușită
func centralManager(
    _ central: CBCentralManager,
    didConnect peripheral: CBPeripheral
) {
    print("Conectat la " +
          "\(peripheral.name ?? "unknown")")

    // Începe descoperirea serviciilor
    peripheral.discoverServices(nil)
}

// Delegat: eroare de conectare
func centralManager(
    _ central: CBCentralManager,
    didFailToConnect peripheral: CBPeripheral,
    error: Error?
) {
    print("Connection failed: 
          \(error?.localizedDescription ?? "")")
}

Timpul de expirare a conexiunii pe iOS este de 30 de secunde. Dacă în acest timp dispozitivul nu răspunde la cererea de conectare, este apelat didFailToConnect. Factorii care influențează expirarea: distanța până la dispozitiv, interferențele, dacă dispozitivul se publicită în acel moment. Înainte de conectare, asigurați-vă că dispozitivul este în modul connectable advertising (ADV_IND, nu ADV_NONCONN_IND).

Descoperirea serviciilor și caracteristicilor

După conectare trebuie descoperite serviciile (discoverServices) și caracteristicile (discoverCharacteristics) ale Peripheral-ului. Acesta este un pas obligatoriu înainte de citirea sau scrierea datelor. Procesul este asincron: discoverServices returnează rezultatul prin peripheral(_:didDiscoverServices:), iar discoverCharacteristics prin peripheral(_:didDiscoverCharacteristicsFor:error:).

Se recomandă să trimiteți în discoverServices un array de UUID-uri de interes, nu nil. Filtrarea accelerează descoperirea și economisește energie. Dacă serviciul nu este găsit, iOS va raporta un array gol. După descoperirea caracteristicilor, puteți citi valorile lor (readValue), vă puteți abona la notificări (setNotifyValue) sau scrie date (writeValue).

Un detaliu important: MTU este negociat automat după conectare. Pentru a obține MTU-ul curent, utilizați peripheral.maximumWriteValueLength(for: .withResponse) sau .withoutResponse. În iOS, MTU-ul maxim este de 512 octeți pentru dispozitivele BLE 5.0. Dacă trebuie să transferați date mai mari decât MTU, implementați fragmentarea la nivelul aplicației.

Scanarea în fundal și limitările iOS

Scanarea în fundal a dispozitivelor BLE pe iOS necesită o configurare specială. Core Bluetooth suportă execuția în fundal, dar cu limitări semnificative. Pentru a funcționa în fundal, este necesar: să activați bluetooth-central în Background Modes în Capabilities ale proiectului, să inițializați CBCentralManager cu opțiunea CBCentralManagerOptionRestoreIdentifierKey pentru state restoration și să gestionați evenimentele managerului central la trecerea în fundal.

Limitările BLE în fundal în iOS: scanForPeripherals fără filtrare după UUID nu funcționează în fundal. Aplicația trebuie să specifice UUID-uri concrete ale serviciilor pentru scanare. iOS poate întârzia livrarea evenimentelor BLE pe o perioadă nedeterminată. Core Bluetooth reia automat scanarea la descoperirea unui dispozitiv potrivit, chiar dacă aplicația este în fundal. Expirarea scanării în fundal: iOS poate opri scanarea după 10–30 de minute pentru economisirea energiei.

State Restoration — mecanismul Core Bluetooth care permite restabilirea conexiunilor BLE după repornirea aplicației sau repornirea iOS. Pentru utilizare: specificați CBCentralManagerOptionRestoreIdentifierKey la inițializare, implementați centralManager(_:willRestoreState:) în delegat și restabiliți lista Peripheral-urilor conectate din dicționarul transmis. State Restoration este o funcționalitate critică pentru aplicațiile BLE care funcționează în fundal, cum ar fi trackerele de fitness sau dispozitivele medicale.

Gestionarea erorilor și restabilirea conexiunii

CBCentralManager generează erori în mai multe scenarii: conexiunea a eșuat (didFailToConnect), conexiunea a fost înreruptă (didDisconnectPeripheral), caracteristica nu este disponibilă pentru citire/scriere (didWriteValue error). Toate erorile Core Bluetooth sunt returnate prin obiectul Error cu domeniul CBErrorDomain. Cele mai frecvente coduri: CBErrorConnectionTimeout (0x04), CBErrorPeripheralDisconnected (0x07), CBErrorOperationNotSupported (0x0A).

Strategia de restabilire a conexiunii: la primirea didDisconnectPeripheral, verificați codul de eroare. Dacă eroarea este CBErrorConnectionTimeout sau CBErrorPeripheralDisconnected — programați reconectarea automată după 1–5 secunde. Dacă eroarea este CBErrorOperationNotSupported — înregistrați și nu încercați să repetați operațiunea. Pentru conexiunile critice (dispozitive medicale), utilizați exponential backoff cu un interval maxim de 60 de secunde.

swift
// Gestionare deconectare cu reconectare automată
func centralManager(
    _ central: CBCentralManager,
    didDisconnectPeripheral peripheral: CBPeripheral,
    error: Error?
) {
    guard let error = error else {
        return // Deconectare așteptată
    }

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

    // Reconectare automată
    if shouldAutoReconnect {
        DispatchQueue.main.asyncAfter(
            deadline: .now() + reconnectDelay
        ) {
            central.connect(peripheral)
        }
    }
}

La dezvoltarea unei aplicații BLE fiabile pe iOS, luați în considerare: Core Bluetooth nu garantează livrarea tuturor pachetelor atunci când semnalul este slab. Pentru un transfer fiabil, utilizați writeType .withResponse (scriere confirmată) și abonați-vă la notificări (setNotifyValue) pentru a primi date de la Peripheral. Păstrați un jurnal al erorilor pentru a diagnostica problemele de conexiune în producție.

întrebări frecvente

De ce CBCentralManager nu detectează dispozitive?

Verificați starea managerului prin centralManagerDidUpdateState. Asigurați-vă că permisiunea NSBluetoothAlwaysUsageDescription există în Info.plist, Bluetooth este activat pe dispozitiv, iar dispozitivul periferic se publicită cu tipul corect (connectable advertising, nu non-connectable).

Câte dispozitive BLE se pot conecta simultan la iOS?

Pe dispozitivele cu BLE 5.0 (iPhone 8 și mai noi) — până la 7 conexiuni simultane. Pe dispozitivele mai vechi — până la 3–5. Numărul de dispozitive scanate este nelimitat, dar conexiunile active au o limită strictă stabilită de Bluetooth Controller.

Cât de des pot scana BLE pe iOS fără a pierde baterie?

Se recomandă scanarea cu filtru după UUID și oprirea scanării atunci când dispozitivul este găsit. Scanarea continuă consumă bateria: 1 oră de scanare neîntreruptă consumă aproximativ 10–15% din bateria iPhone. Utilizați temporizatoare și condiții pentru a opri scanarea.

Care este diferența între CBCentralManager și CBPeripheralManager?

CBCentralManager — pentru scanarea și conectarea la dispozitive BLE externe (rol Central). CBPeripheralManager — pentru ca dispozitivul iOS să acționeze ca periferic BLE (să publice servicii). O instanță poate fi doar într-un singur rol.

Cum gestionăm pierderea conexiunii cu un dispozitiv BLE?

Implementați centralManager(_:didDisconnectPeripheral:error:). Dacă eroarea nu este nil — programați reconectarea automată cu exponential backoff (1 s → 2 s → 4 s → 8 s → max 60 s). Dacă eroarea este nil — dispozitivul s-a deconectat normal (de exemplu, utilizatorul a apăsat un buton pe dispozitiv).

Rezumat

  • CBCentralManager — clasa principală Core Bluetooth pentru gestionarea scanării BLE, conectării și transferului de date în rolul Central pe iOS.
  • Scanarea se pornește prin scanForPeripherals cu filtrare opțională după UUID-urile serviciilor pentru reducerea consumului de energie.
  • Conectarea se realizează prin connect, succesul este confirmat prin didConnect, eroarea prin didFailToConnect cu expirare de 30 de secunde.
  • După conectare, trebuie descoperite serviciile și caracteristicile prin discoverServices și discoverCharacteristics.
  • Scanarea în fundal necesită modul Background bluetooth-central și este suportată cu limitări (filtrare după UUID, posibile întârzieri).
  • iOS suportă până la 7 conexiuni BLE simultane pe dispozitive cu BLE 5.0, state restoration pentru restabilirea după repornire.
  • Gestionarea erorilor și reconectarea automată cu exponential backoff — baza unei aplicații BLE fiabile pe iOS.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și