CBCentralManager — is de centrale klasse van het Core Bluetooth-framework in iOS, die het scannen, verbinden en communiceren met BLE-randapparaten beheert. Core Bluetooth (iOS 5+, 2011) biedt een hoogwaardige abstractie over de BLE-stack op GATT-niveau, en verbergt de details van Link Layer en HCI voor de ontwikkelaar. CBCentralManager vervult de rol van Central: het scant de ether via scanForPeripherals, initieert verbinding via connect, ontdekt services via discoverServices en beheert gegevensoverdracht. Volgens Apple Developer Documentation (2024) ondersteunt CBCentralManager tot 7 gelijktijdige BLE-verbindingen op apparaten met BLE 5.0.
Belangrijkste punten
CBCentralManager — is de hoofdklasse van Core Bluetooth voor het implementeren van de Central-rol in de BLE-architectuur op iOS. Het beheert de volledige levenscyclus van een BLE-verbinding: van het scannen van adverterende apparaten tot gegevensoverdracht en verbreken. CBCentralManager werkt asynchroon via de CBCentralManagerDelegate, die de app op de hoogte stelt van gebeurtenissen in de Bluetooth-stack.
Initialisatie van CBCentralManager start het state restoration-proces: de manager controleert de Bluetooth-status op het apparaat en herstelt eerdere verbindingen als de app was gesloten. Het initialisatieproces kan 50 tot 500 ms duren, afhankelijk van de Bluetooth-status. De app moet wachten op de aanroep van centralManagerDidUpdateState voordat BLE-bewerkingen worden gestart.
De architectuur van Core Bluetooth is gebaseerd op het Delegation-patroon: CBCentralManager delegeert gebeurtenisafhandeling (apparaatdetectie, verbinding, fouten) aan het CBCentralManagerDelegate-protocol. Voor het werken met een specifieke Peripheral wordt het CBPeripheralDelegate-protocol gebruikt, dat op de hoogte stelt van ontdekte services, kenmerken en ontvangen gegevens. Dit asynchrone model zorgt voor een niet-blokkerende werking van de UI.
CBCentralManager doorloopt verschillende statussen die bepalen of de BLE-stack beschikbaar is voor gebruik. De status wordt doorgegeven via de delegate: centralManagerDidUpdateState(_:). De ontwikkelaar moet alle statussen afhandelen — niet alleen poweredOn, maar ook gevallen waarin Bluetooth is uitgeschakeld of niet beschikbaar is.
| Status | Betekenis | Actie ontwikkelaar |
|---|---|---|
| .poweredOn | Bluetooth is ingeschakeld en gereed | Start scannen |
| .poweredOff | Bluetooth is uitgeschakeld | Toon melding aan gebruiker |
| .unauthorized | Geen toestemming | Vraag toestemming in Instellingen |
| .unsupported | Apparaat ondersteunt geen BLE | Verberg BLE-functies |
| .unknown | Status niet gedefinieerd | Wacht op volgende update |
| .resetting | Bluetooth wordt opnieuw gestart | Wacht op herstel |
Unauthorized state komt steeds vaker voor sinds iOS 13+. Vanaf deze versie moet de app de machtiging NSBluetoothAlwaysUsageDescription in Info.plist hebben. Zonder deze machtiging gaat de centrale manager naar de status .unauthorized en is scannen onmogelijk. De gebruiker kan de machtiging op elk moment wijzigen in Instellingen > Privacy > Bluetooth.
scanForPeripherals(withServices:options:) — de belangrijkste methode om te starten met scannen. De parameter withServices accepteert een reeks service-UUIDs voor filtering: als nil wordt doorgegeven, worden alle apparaten gedetecteerd, wat het energieverbruik aanzienlijk verhoogt. Het wordt aanbevolen altijd te filteren op UUIDs van services die de app nodig heeft. Scanopties omvatten CBCentralManagerScanOptionAllowDuplicatesKey (herhaalde meldingen over hetzelfde apparaat).
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") // Batterijservice
centralManager.scanForPeripherals(
withServices: [serviceUUID],
options: [
CBCentralManagerScanOptionAllowDuplicatesKey: false
]
)
}
}
Bij detectie van een apparaat wordt centralManager(_:didDiscover:advertisementData:rssi:) aangeroepen. De parameter advertisementData bevat een volledig woordenboek van de advertentiepakketgegevens, inclusief de apparaatnaam (CBAdvertisementDataLocalNameKey), service-UUIDs (CBAdvertisementDataServiceUUIDsKey) en fabrikantgegevens (CBAdvertisementDataManufacturerDataKey). RSSI — het signaalniveau in dBm, beschikbaar op het moment van detectie.
connect(_:options:) — methode voor het tot stand brengen van een BLE-verbinding met een gedetecteerde Peripheral. Na de aanroep van connect probeert iOS verbinding te maken met het apparaat. Een succesvolle verbinding wordt bevestigd door centralManager(_:didConnect:), een fout door centralManager(_:didFailToConnect:error:). Verbindingsopties omvatten CBConnectPeripheralOptionNotifyOnConnectionKey, CBConnectPeripheralOptionNotifyOnDisconnectionKey en CBConnectPeripheralOptionNotifyOnNotificationKey voor achtergrondmeldingen.
// Verbinding maken met BLE-apparaat
func connectToPeripheral(
_ peripheral: CBPeripheral
) {
centralManager.connect(peripheral, options: nil)
// Stel delegate in voor Peripheral
peripheral.delegate = self
}
// Delegate: succesvolle verbinding
func centralManager(
_ central: CBCentralManager,
didConnect peripheral: CBPeripheral
) {
print("Verbonden met " +
"\(peripheral.name ?? "unknown")")
// Start service-ontdekking
peripheral.discoverServices(nil)
}
// Delegate: verbindingsfout
func centralManager(
_ central: CBCentralManager,
didFailToConnect peripheral: CBPeripheral,
error: Error?
) {
print("Connection failed:
\(error?.localizedDescription ?? "")")
}
Verbindingstime-out op iOS is 30 seconden. Als het apparaat binnen deze tijd niet reageert op het verbindingsverzoek, wordt didFailToConnect aangeroepen. Factoren die de time-out beïnvloeden: afstand tot het apparaat, interferentie, of het apparaat op dat moment adverteert. Zorg ervoor dat het apparaat zich in de connectable advertising-modus bevindt (ADV_IND, niet ADV_NONCONN_IND) voordat u verbinding maakt.
Na verbinding moeten de services (discoverServices) en kenmerken (discoverCharacteristics) van de Peripheral worden ontdekt. Dit is een verplichte stap voordat gegevens worden gelezen of geschreven. Het proces is asynchroon: discoverServices retourneert het resultaat via peripheral(_:didDiscoverServices:), en discoverCharacteristics via peripheral(_:didDiscoverCharacteristicsFor:error:).
Het wordt aanbevolen om in discoverServices een reeks interessante UUIDs door te geven in plaats van nil. Filteren versnelt de detectie en bespaart energie. Als de service niet wordt gevonden, meldt iOS een lege reeks. Na detectie van kenmerken kunnen hun waarden worden gelezen (readValue), kunnen meldingen worden geabonneerd (setNotifyValue) of kunnen gegevens worden geschreven (writeValue).
Een belangrijke nuance: MTU wordt automatisch overeengekomen na verbinding. Gebruik peripheral.maximumWriteValueLength(for: .withResponse) of .withoutResponse om de huidige MTU te verkrijgen. In iOS is de maximale MTU 512 bytes voor BLE 5.0-apparaten. Als u gegevens groter dan de MTU moet overdragen, implementeer dan fragmentatie op applicatieniveau.
Achtergrondscannen van BLE-apparaten op iOS vereist speciale configuratie. Core Bluetooth ondersteunt achtergronduitvoering, maar met aanzienlijke beperkingen. Voor achtergrondwerking is nodig: bluetooth-central inschakelen in Background Modes in de Capabilities van het project, CBCentralManager initialiseren met de optie CBCentralManagerOptionRestoreIdentifierKey voor state restoration, en gebeurtenissen van de centrale manager afhandelen bij het overgaan naar de achtergrond.
BLE-beperkingen op de achtergrond in iOS: scanForPeripherals zonder UUID-filtering werkt niet op de achtergrond. De app moet specifieke service-UUIDs opgeven om te scannen. iOS kan de levering van BLE-gebeurtenissen voor onbepaalde tijd vertragen. Core Bluetooth hervat automatisch het scannen bij detectie van een overeenkomend apparaat, zelfs als de app op de achtergrond is. Time-out voor achtergrondscannen: iOS kan het scannen na 10–30 minuten stoppen om energie te besparen.
State Restoration — het Core Bluetooth-mechanisme dat het mogelijk maakt BLE-verbindingen te herstellen na het opnieuw opstarten van de app of een iOS-reboot. Voor gebruik: specificeer CBCentralManagerOptionRestoreIdentifierKey bij initialisatie, implementeer centralManager(_:willRestoreState:) in de delegate en herstel de lijst met verbonden Peripherals uit het doorgegeven woordenboek. State Restoration is een kritieke functionaliteit voor BLE-apps die op de achtergrond werken, zoals fitnesstrackers of medische apparaten.
CBCentralManager genereert fouten in verschillende scenario’s: verbinding mislukt (didFailToConnect), verbinding verbroken (didDisconnectPeripheral), kenmerk niet beschikbaar voor lezen/schrijven (didWriteValue error). Alle Core Bluetooth-fouten worden geretourneerd via het Error-object met domein CBErrorDomain. De meest voorkomende codes: CBErrorConnectionTimeout (0x04), CBErrorPeripheralDisconnected (0x07), CBErrorOperationNotSupported (0x0A).
Strategie voor het herstellen van de verbinding: controleer bij ontvangst van didDisconnectPeripheral de foutcode. Als de fout CBErrorConnectionTimeout of CBErrorPeripheralDisconnected is — plan automatisch opnieuw verbinden na 1–5 seconden. Als de fout CBErrorOperationNotSupported is — log en probeer de bewerking niet te herhalen. Gebruik voor kritieke verbindingen (medische apparaten) exponential backoff met een maximum interval van 60 seconden.
// Verbreken afhandelen met automatisch opnieuw verbinden
func centralManager(
_ central: CBCentralManager,
didDisconnectPeripheral peripheral: CBPeripheral,
error: Error?
) {
guard let error = error else {
return // Verwacht verbreken
}
print("Disconnected: \(error.localizedDescription)")
// Automatisch opnieuw verbinden
if shouldAutoReconnect {
DispatchQueue.main.asyncAfter(
deadline: .now() + reconnectDelay
) {
central.connect(peripheral)
}
}
}
Houd bij het ontwikkelen van een betrouwbare BLE-app op iOS rekening met: Core Bluetooth garandeert niet de levering van alle pakketten bij een zwak signaal. Gebruik voor betrouwbare overdracht writeType .withResponse (bevestigd schrijven) en abonneer u op meldingen (setNotifyValue) om gegevens van Peripheral te ontvangen. Houd een foutenlogboek bij voor het diagnosticeren van verbindingsproblemen in de productie.
Veelgestelde vragen
Controleer de status van de manager via centralManagerDidUpdateState. Zorg ervoor dat de machtiging NSBluetoothAlwaysUsageDescription aanwezig is in Info.plist, Bluetooth is ingeschakeld op het apparaat en het randapparaat adverteert met het juiste type (connectable advertising, niet non-connectable).
Op apparaten met BLE 5.0 (iPhone 8 en nieuwer) — tot 7 gelijktijdige verbindingen. Op oudere apparaten — tot 3–5. Het aantal gescande apparaten is onbeperkt, maar actieve verbindingen hebben een strikte limiet ingesteld door de Bluetooth Controller.
Het wordt aanbevolen te scannen met een UUID-filter en het scannen uit te schakelen wanneer het apparaat is gevonden. Continu scannen verbruikt de batterij: 1 uur onafgebroken scannen verbruikt ongeveer 10–15% van de iPhone-batterij. Gebruik timers en voorwaarden om het scannen te stoppen.
CBCentralManager — voor het scannen en verbinden met externe BLE-apparaten (Central-rol). CBPeripheralManager — zodat uw iOS-apparaat zelf als BLE-randapparaat fungeert (services adverteert). Eén exemplaar kan slechts in één rol zijn.
Implementeer centralManager(_:didDisconnectPeripheral:error:). Als de fout niet nil is — plan automatisch opnieuw verbinden met exponential backoff (1 s → 2 s → 4 s → 8 s → max 60 s). Als de fout nil is — het apparaat is normaal verbroken (bijvoorbeeld de gebruiker heeft op een knop op het apparaat gedrukt).
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook