Core Bluetooth: architectuur en BLE-ontwikkeling op iOS

Auteur: IT Sectr Gepubliceerd: 2026-07-16 Leestijd: 10 min

Core Bluetooth is het Apple-framework voor interactie met Bluetooth Low Energy op iOS, iPadOS en macOS. Het framework biedt een volledige set API's voor het werken in beide BLE-rollen: centraal apparaat (CBCentralManager) voor het scannen en verbinden met randapparatuur en randapparaat (CBPeripheralManager) voor het emuleren van een BLE-server. Core Bluetooth abstraheert de BLE-protocolstack van de fysieke radio tot het toepassings-GATT-profiel. Volgens Apple Developer, 2026 is Core Bluetooth de enige officiële Apple API voor BLE-ontwikkeling, met ondersteuning voor BLE 4.0–5.4 met extended advertising, 2M PHY en LE Audio.

Belangrijkste Punten

  • Core Bluetooth — het systeemframework van Apple voor BLE-ontwikkeling op iOS, iPadOS en macOS
  • CBCentralManager — klasse voor het scannen en verbinden met BLE-randapparatuur vanuit het centrale apparaat
  • CBPeripheralManager — klasse voor het maken van een BLE-server die services en kenmerken publiceert
  • GATT-profiel — hiërarchisch model van services, kenmerken en descriptoren voor gegevensuitwisseling
  • Achtergrondmodi — Core Bluetooth ondersteunt BLE-communicatie op de achtergrond via systeemdelegaten en state restoration

Wat is Core Bluetooth: architectuur en componenten

Core Bluetooth verdeelt de BLE-stack in twee logische rollen gedefinieerd door de Bluetooth SIG-specificatie. De rol van centraal apparaat (Central) wordt vertegenwoordigd door de klasse CBCentralManager — initieert scannen, maakt verbindingen en beheert de lijst met verbonden CBPeripherals. De rol van randapparaat (Peripheral) wordt vertegenwoordigd door CBPeripheralManager — publiceert services en kenmerken, reageert op verzoeken van de centrale en stuurt meldingen. Een iOS-sessie kan gelijktijdig in beide rollen werken op verschillende BLE-radio's, maar een typische app gebruikt één rol.

De architectuur van Core Bluetooth omvat vijf belangrijke abstracties. CBCentralManager beheert de status van de Bluetooth-adapter van het apparaat: poweredOn (klaar voor gebruik), poweredOff (Bluetooth uitgeschakeld), unauthorized (geen toestemming), unsupported (BLE niet beschikbaar). CBPeripheral vertegenwoordigt een extern BLE-apparaat met zijn UUID, naam, RSSI en GATT-hiërarchie. CBService — een logische groep kenmerken. CBCharacteristic — een gegevenspunt voor lezen/schrijven/meldingen. CBPeripheralManager maakt een lokale GATT-server voor het emuleren van randapparatuur.

KlasseRolBelangrijkste methoden
CBCentralManagerCentraal apparaatscanForPeripherals, connect, cancelPeripheralConnection, retrievePeripherals
CBPeripheralExtern randapparaatdiscoverServices, discoverCharacteristics, readValue, writeValue, setNotifyValue
CBPeripheralManagerLokaal randapparaataddService, removeService, startAdvertising, respondToRequest, updateValue
CBCentralExterne centralemaximumUpdateValueLength, identifier, ancsAuthorized

CBCentralManager-statussen beheren alle BLE-operaties. Bij het starten van de app wordt centralManagerDidUpdateState aangeroepen met de huidige Bluetooth-status. Als de status niet .poweredOn is, worden alle BLE-aanroepen door het systeem genegeerd. De ontwikkelaar moet state controleren vóór elke scan en verbinding. De overgang van .poweredOff naar .poweredOn vindt plaats wanneer Bluetooth wordt ingeschakeld in iOS Instellingen — de delegaat krijgt een herhaalde aanroep en de app kan het scannen hervatten.

CBCentralManager: scannen en verbinden van BLE-apparaten

CBCentralManager is het toegangspunt voor alle BLE-operaties vanaf het centrale apparaat. Initialisatie ontvangt een delegaat (CBCentralManagerDelegate) en een DispatchQueue-wachtrij — Apple adviseert main queue voor eenvoud of serial queue voor prestaties. Na initialisatie controleert het framework automatisch de Bluetooth-status en roept centralManagerDidUpdateState: aan — de eerste verplichte delegaat voor verwerking.

Scannen wordt gestart met de methode scanForPeripheralsWithServices:options:. De eerste parameter is een array van CBUUIDs van services om te filteren: als de UUIDs van interessante services bekend zijn, vermindert het doorgeven ervan het energieverbruik en de zoektijd. Indien nil, worden alle BLE-apparaten binnen bereik gedetecteerd. Opties omvatten .allowDuplicatesKey (herhaalde detectie van hetzelfde apparaat) en .solicitedServiceUUIDsKey (voor services gepubliceerd op de centrale).

swift
import CoreBluetooth

class BLECentral: NSObject {

    private var centralManager: CBCentralManager!
    private var discoveredPeripherals: [CBPeripheral] = []

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

    // BLE-scannen starten
    func startScan() {
        guard centralManager.state == .poweredOn else {
            print("Bluetooth niet beschikbaar")
            return
        }
        // Alle apparaten scannen (nil = geen filter)
        centralManager.scanForPeripherals(withServices: nil,
                                            options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
    }

    // Scannen stoppen
    func stopScan() {
        centralManager.stopScan()
    }

    // Verbinden met geselecteerd apparaat
    func connect(to peripheral: CBPeripheral) {
        centralManager.connect(peripheral, options: nil)
    }
}

// MARK: - CBCentralManagerDelegate
extension BLECentral: CBCentralManagerDelegate {

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOn {
            startScan()
        }
    }

    func centralManager(_ central: CBCentralManager,
                        didDiscover peripheral: CBPeripheral,
                        advertisementData: [String : Any],
                        rssi: NSNumber) {
        if !discoveredPeripherals.contains(where: { $0.identifier == peripheral.identifier }) {
            discoveredPeripherals.append(peripheral)
            print("Found devices: \(peripheral.name ?? "Unknown"), RSSI: \(rssi)")
        }
    }

    func centralManager(_ central: CBCentralManager,
                        didConnect peripheral: CBPeripheral) {
        print("Connected: \(peripheral.identifier)")
        peripheral.delegate = self
        peripheral.discoverServices(nil)
    }

    func centralManager(_ central: CBCentralManager,
                        didDisconnectPeripheral peripheral: CBPeripheral,
                        error: Error?) {
        print("Disconnected: \(peripheral.identifier)")
    }
}

De klasse BLECentral toont de volledige cyclus van scannen en verbinden van BLE-apparaten. centralManagerDidUpdateState start scannen wanneer Bluetooth is ingeschakeld. didDiscoverPeripheral verzamelt gevonden apparaten in de array discoveredPeripherals met deduplicatie op identifier. Na verbinding (didConnect) wordt onmiddellijk service-discovery gestart — dit is een verplichte stap vóór GATT-operaties.

CBPeripheralManager: een BLE-server maken op iOS

CBPeripheralManager is de klasse voor het emuleren van een BLE-randapparaat op iOS. Een app in de randapparaatrol kan zijn eigen services en kenmerken publiceren, inkomende lees-/schrijfverzoeken van het centrale apparaat ontvangen en meldingen sturen. CBPeripheralManager wordt gebruikt voor BLE-accessoires geëmuleerd door iPhone: afstandsbedieningen, toetsenborden, trackers, IoT-gateways.

De levenscyclus van CBPeripheralManager begint met initialisatie en de CBPeripheralManagerDelegate-delegaat. Na bevestiging van poweredOn via peripheralManagerDidUpdateState: worden services gepubliceerd (addService:) en wordt advertising gestart (startAdvertising:). CBAdvertisementData-advertentiegegevens omvatten de lokale naam (CBAdvertisementDataLocalNameKey), service-UUIDs (CBAdvertisementDataServiceUUIDsKey) en het vermogensniveau (CBAdvertisementDataTxPowerLevelKey). De maximale grootte van een advertentiepakket is 31 bytes voor BLE 4.0, 251 bytes voor extended advertising BLE 5.0+.

swift
// BLE-randapparaat op iOS via CBPeripheralManager
class BLEPeripheral: NSObject {

    private var peripheralManager: CBPeripheralManager!

    let serviceUUID = CBUUID(string: "1234")
    let characteristicUUID = CBUUID(string: "5678")

    override init() {
        super.init()
        peripheralManager = CBPeripheralManager(delegate: self, queue: .main)
    }

    // Service met kenmerk publiceren
    func setupService() {
        let characteristic = CBMutableCharacteristic(
            type: characteristicUUID,
            properties: [.read, .write, .notify],
            value: nil,
            permissions: [.readable, .writeable]
        )
        let service = CBMutableService(type: serviceUUID, primary: true)
        service.characteristics = [characteristic]
        peripheralManager.add(service)
    }

    // Adverteren starten
    func startAdvertising() {
        let advertisementData: [String: Any] = [
            CBAdvertisementDataLocalNameKey: "My BLE Device",
            CBAdvertisementDataServiceUUIDsKey: [serviceUUID]
        ]
        peripheralManager.startAdvertising(advertisementData)
    }
}

// MARK: - CBPeripheralManagerDelegate
extension BLEPeripheral: CBPeripheralManagerDelegate {

    func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
        if peripheral.state == .poweredOn {
            setupService()
        }
    }

    func peripheralManager(_ peripheral: CBPeripheralManager,
                        didAdd service: CBService,
                        error: Error?) {
        if error == nil {
            startAdvertising()
        }
    }

    // Leesverzoek afhandelen
    func peripheralManager(_ peripheral: CBPeripheralManager,
                        didReceiveRead request: CBATTRequest) {
        let data = "CurrentValue".data(using: .utf8)!
        request.value = data
        peripheralManager.respond(to: request, withResult: .success)
    }

    // Schrijfverzoek afhandelen
    func peripheralManager(_ peripheral: CBPeripheralManager,
                        didReceiveWrite requests: [CBATTRequest]) {
        for request in requests {
            if let value = request.value {
                print("Write: \(value)")
            }
        }
        peripheralManager.respond(to: requests.first!, withResult: .success)
    }
}

De klasse BLEPeripheral maakt een BLE-server met één kenmerk dat lezen, schrijven en meldingen ondersteunt. Na initialisatie publiceert peripheralManagerDidUpdateState de service via addService: en start vervolgens advertising via startAdvertising:. De handlers didReceiveRead en didReceiveWrite reageren op inkomende GATT-verzoeken van het centrale apparaat. Voor het verzenden van meldingen wordt de methode updateValue:forCharacteristic:onSubscribedCentrals: gebruikt.

GATT-operaties: lezen, schrijven en meldingen

GATT-operaties (Generic Attribute Profile) vormen de basis van gegevensuitwisseling in Core Bluetooth. Na discovery van services en kenmerken kan het centrale apparaat drie soorten operaties uitvoeren: lezen van de waarde van een kenmerk, schrijven van een waarde en abonneren op meldingen/indicaties. Elke operatie is asynchroon en retourneert het resultaat via de bijbehorende CBPeripheralDelegate-delegaat.

Lezen wordt uitgevoerd door readValueForCharacteristic: aan te roepen. De waarde komt binnen in peripheral:didUpdateValueForCharacteristic:error:. Belangrijk: lezen retourneert de huidige waarde van het apparaat, niet een gecachte. Als het apparaat lezen niet ondersteunt (eigenschap .read), retourneert de aanroep een fout. Voor grote waarden (groter dan MTU) fragmenteert en monteert BLE automatisch gegevens op GATT-niveau.

Schrijven wordt uitgevoerd door writeValue:forCharacteristic:type:. BLE ondersteunt twee schrijfmodellen: withResponse (betrouwbaar, met bevestiging) en withoutResponse (snel, zonder bevestiging). De eigenschap CBCharacteristic.properties bepaalt de beschikbare schrijftypen. De maximale grootte van een enkel schrijfpakket is beperkt door MTU: 23 bytes voor BLE 4.0 (20 bytes nuttige gegevens + 3 bytes header), tot 247 bytes voor BLE 5.0 met extended MTU (MTU 251).

Meldingen worden geactiveerd door setNotifyValue:true forCharacteristic: aan te roepen. Na abonnering stuurt het randapparaat automatisch updates via peripheral:didUpdateValueForCharacteristic: telkens wanneer de waarde van het kenmerk verandert. Om meldingen uit te schakelen wordt setNotifyValue:false forCharacteristic: aangeroepen. Core Bluetooth beheert automatisch de CCCD-descriptor op het randapparaat.

OperatieMethodeDelegaatTransmissietype
LezenreadValueForCharacteristic:didUpdateValueForCharacteristicPolling (verzoek-antwoord)
Schrijven withResponsewriteValue:forCharacteristic:type:withResponsedidWriteValueForCharacteristicMet bevestiging
Schrijven withoutResponsewriteValue:forCharacteristic:type:withoutResponseGeen delegaatZonder bevestiging
MeldingsetNotifyValue:true forCharacteristic:didUpdateNotificationStateForCharacteristic + didUpdateValueForCharacteristicPush van randapparaat

Achtergrondmodus van Core Bluetooth en State Restoration

Achtergrondmodus van Core Bluetooth stelt een BLE-app in staat om te blijven scannen, verbindingen te behouden en meldingen te ontvangen terwijl deze op de achtergrond draait. Voor activering is vereist: schakel capability „Uses Bluetooth LE accessories” in Xcode in (Info.plist → Required background modes → App communicates using Core Bluetooth) en voeg de sleutel „bluetooth-central” toe aan UIBackgroundModes. Voor de randapparaatrol — „bluetooth-peripheral”.

State Restoration is het mechanisme van Core Bluetooth voor het herstellen van de status van BLE-verbindingen na herstart van de app door het iOS-systeem. Bij activering van de achtergrondmodus en het opgeven van restoreIdentifier bij initialisatie van CBCentralManager of CBPeripheralManager, slaat iOS de status van de BLE-stack op bij beëindiging van de app en herstelt deze bij de volgende start. De delegaat centralManager:willRestoreState: ontvangt een woordenboek met opgeslagen CBPeripherals en wachtende verbindingen.

swift
// Core Bluetooth configuratie met State Restoration
class BLECentralWithRestoration: NSObject {

    let restoreIdentifier = "com.app.blecentral"
    private var centralManager: CBCentralManager!

    override init() {
        super.init()
        let options: [String: Any] = [
            CBCentralManagerOptionRestoreIdentifierKey: restoreIdentifier,
            CBCentralManagerOptionShowPowerAlertKey: true
        ]
        centralManager = CBCentralManager(delegate: self,
                                          queue: nil,
                                          options: options)
    }
}

extension BLECentralWithRestoration: CBCentralManagerDelegate {

    // Status herstellen na herstart
    func centralManager(_ central: CBCentralManager,
                        willRestoreState dict: [String : Any]) {
        if let peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey]
            as? [CBPeripheral] {
            for peripheral in peripherals {
                peripheral.delegate = self
                // GATT-discovery herstellen
                peripheral.discoverServices(nil)
            }
        }
    }

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOn {
            print("Bluetooth gereed na herstel")
        }
    }
}

In de configuratie BLECentralWithRestoration activeert de sleutel CBCentralManagerOptionRestoreIdentifierKey het opslaan van de status. Als de app is beëindigd door iOS (bijvoorbeeld door geheugengebrek), ontvangt centralManager:willRestoreState: bij de volgende start de lijst met eerder verbonden CBPeripherals. De app herstelt delegaten en voert opnieuw service-discovery uit — de gebruiker merkt geen verbindingsonderbreking. Zonder State Restoration gaan alle BLE-sessies verloren bij beëindiging van de app.

Voorbeeld van een BLE-app in Swift: centraal en randapparaat

Volledig voorbeeld van een BLE-app in Swift combineert het centrale en randapparaat in één project. De app kan in twee modi werken: BLE-apparaten detecteren en ermee verbinden (Central) of een BLE-accessoire emuleren (Peripheral). Hieronder wordt de architectuur gepresenteerd met een gemeenschappelijke BLE-beheerder die bij het opstarten een rol kiest.

swift
// Universele BLE-beheerder voor centraal en randapparaat
class BLEManager {

    enum Role {
        case central
        case peripheral
    }

    private let role: Role
    private var centralManager: CBCentralManager?
    private var peripheralManager: CBPeripheralManager?
    let advertisedServiceUUID = CBUUID(string: "A001")

    init(role: Role) {
        self.role = role
        switch role {
        case .central:
            centralManager = CBCentralManager(delegate: nil, queue: .main)
        case .peripheral:
            peripheralManager = CBPeripheralManager(delegate: nil, queue: .main)
        }
    }

    // Centraal apparaat: scannen
    func scanForDevices() {
        centralManager?.scanForPeripherals(withServices: nil, options: nil)
    }

    // Randapparaat: adverteren
    func advertiseService() {
        let data: [String: Any] = [
            CBAdvertisementDataServiceUUIDsKey: [advertisedServiceUUID]
        ]
        peripheralManager?.startAdvertising(data)
    }
}

// Gebruik bij opstarten
let isCentral = UserDefaults.standard.bool(forKey: "isCentral")
let manager = BLEManager(role: isCentral ? .central : .peripheral)

if isCentral {
    manager.scanForDevices()
} else {
    manager.advertiseService()
}

De beheerder BLEManager kiest bij initialisatie een rol en maakt de bijbehorende Manager (CBCentralManager of CBPeripheralManager). De rolvlag kan worden opgeslagen in UserDefaults of worden doorgegeven via een configuratieserver. Deze aanpak stelt de BLE-app in staat zich aan te passen aan het gebruiksscenario: op een verkooppunt werkt de iPhone als centrale voor het scannen van betalingsterminals, op een IoT-gateway als randapparaat voor het verzamelen van sensorgegevens.

Veelgestelde vragen

Wat is Core Bluetooth?

Core Bluetooth is het Apple-framework voor BLE-ontwikkeling op iOS, iPadOS en macOS. Het biedt API's voor het werken van het centrale (CBCentralManager) en randapparaat (CBPeripheralManager). Het ondersteunt BLE 4.0–5.4, extended advertising, 2M PHY en LE Audio. Core Bluetooth is de enige officiële Apple API voor BLE-communicatie, verplicht voor alle iOS-apps die met Bluetooth Low Energy werken.

Wat is het verschil tussen CBCentralManager en CBPeripheralManager?

CBCentralManager is de klasse voor het werken in de rol van centraal apparaat: scant BLE-randapparatuur, maakt verbindingen, leest en schrijft kenmerken. CBPeripheralManager is de klasse voor het werken in de rol van randapparaat: publiceert services, reageert op lees-/schrijfverzoeken en stuurt meldingen. Eén iPhone kan gelijktijdig in twee rollen werken via verschillende beheerinstanties.

Hoe configureer ik Core Bluetooth voor achtergrondwerk?

Voor BLE-achtergrondwerk schakelt u capability „Uses Bluetooth LE accessories” in Xcode in en voegt u de sleutel „bluetooth-central” toe aan UIBackgroundModes. Voor de randapparaatrol — „bluetooth-peripheral”. Geef restoreIdentifier op bij initialisatie van de beheerder voor State Restoration. Zonder deze instellingen ontvangt de app op de achtergrond geen BLE-gebeurtenissen en verliest hij verbindingen.

Waarom vindt Core Bluetooth geen apparaten?

Belangrijkste oorzaken: CBCentralManager.state != .poweredOn (Bluetooth uitgeschakeld of niet geautoriseerd), delegaat niet ingesteld, apparaat buiten bereik of verzendt geen advertentiepakketten. Controleer de machtiging NSBluetoothAlwaysUsageDescription in Info.plist, de Bluetooth-status in centralManagerDidUpdateState en zorg ervoor dat scanForPeripherals alleen wordt aangeroepen bij .poweredOn.

Kunnen meerdere CBPeripherals tegelijk worden verbonden?

Ja, Core Bluetooth ondersteunt gelijktijdige verbinding met meerdere BLE-apparaten. Elke CBPeripheral wordt onafhankelijk beheerd via zijn eigen delegaat. iOS beperkt het aantal gelijktijdige BLE-verbindingen op systeemniveau (meestal 5–7 voor iPhone). Voor 1:N-scenario's (bijvoorbeeld een fitnesscentrum met 10 trackers) is wachtrijplaatsing en cyclische bediening van randapparatuur vereist.

Samenvatting

  • Core Bluetooth is het systeemframework van Apple voor BLE-ontwikkeling met de klassen CBCentralManager en CBPeripheralManager
  • CBCentralManager beheert scannen, verbinden en GATT-operaties met externe BLE-apparaten
  • CBPeripheralManager emuleert BLE-randapparatuur met publicatie van services en verwerking van inkomende verzoeken
  • GATT-profiel omvat services, kenmerken en descriptoren met lees-, schrijf- en meldingsoperaties
  • Achtergrondmodus vereist UIBackgroundModes en restoreIdentifier voor State Restoration
  • MTU van BLE beperkt de pakketgrootte: 23 bytes voor BLE 4.0, tot 251 bytes voor BLE 5.0+ met extended MTU
  • Swift async/await via CheckedContinuation vereenvoudigt asynchrone BLE-code met delegaten

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.

Bespreek het project

Lees ook