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 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.
| Klasse | Rol | Belangrijkste methoden |
|---|---|---|
| CBCentralManager | Centraal apparaat | scanForPeripherals, connect, cancelPeripheralConnection, retrievePeripherals |
| CBPeripheral | Extern randapparaat | discoverServices, discoverCharacteristics, readValue, writeValue, setNotifyValue |
| CBPeripheralManager | Lokaal randapparaat | addService, removeService, startAdvertising, respondToRequest, updateValue |
| CBCentral | Externe centrale | maximumUpdateValueLength, 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 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).
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 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+.
// 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 (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.
| Operatie | Methode | Delegaat | Transmissietype |
|---|---|---|---|
| Lezen | readValueForCharacteristic: | didUpdateValueForCharacteristic | Polling (verzoek-antwoord) |
| Schrijven withResponse | writeValue:forCharacteristic:type:withResponse | didWriteValueForCharacteristic | Met bevestiging |
| Schrijven withoutResponse | writeValue:forCharacteristic:type:withoutResponse | Geen delegaat | Zonder bevestiging |
| Melding | setNotifyValue:true forCharacteristic: | didUpdateNotificationStateForCharacteristic + didUpdateValueForCharacteristic | Push van randapparaat |
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.
// 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.
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.
// 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
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.
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.
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.
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.
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
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