CBCentralManager — je centrální třída frameworku Core Bluetooth v iOS, která spravuje skenování, připojování a interakci s periferními zařízeními BLE. Core Bluetooth (iOS 5+, 2011) poskytuje vysoceúrovňovou abstrakci nad BLE zásobníkem na úrovni GATT, skrývající před vývojářem detaily Link Layer a HCI. CBCentralManager vykonává roli Central: skenuje éter pomocí scanForPeripherals, iniciuje připojení pomocí connect, objevuje služby pomocí discoverServices a spravuje přenos dat. Podle Apple Developer Documentation (2024) podporuje CBCentralManager až 7 současných BLE připojení na zařízeních s BLE 5.0.
Hlavní body
CBCentralManager — je hlavní třída Core Bluetooth pro implementaci role Central v BLE architektuře na iOS. Spravuje celý životní cyklus BLE připojení: od skenování inzerujících zařízení až po přenos dat a odpojení. CBCentralManager pracuje asynchronně prostřednictvím delegáta CBCentralManagerDelegate, který informuje aplikaci o událostech v Bluetooth zásobníku.
Inicializace CBCentralManager spouští proces state restoration: manažer zkontroluje stav Bluetooth na zařízení a obnoví předchozí připojení, pokud byla aplikace zavřena. Proces inicializace může trvat 50 až 500 ms v závislosti na stavu Bluetooth. Aplikace musí počkat na volání centralManagerDidUpdateState před zahájením jakýchkoli BLE operací.
Architektura Core Bluetooth je postavena na vzoru Delegation: CBCentralManager deleguje zpracování událostí (objevování zařízení, připojování, chyby) na protokol CBCentralManagerDelegate. Pro práci s konkrétním Peripheral se používá protokol CBPeripheralDelegate, který informuje o objevení služeb, charakteristik a přijetí dat. Tento asynchronní model zajišťuje neblokující chod UI.
CBCentralManager prochází několika stavy, které určují, zda je BLE zásobník dostupný pro práci. Stav je předáván prostřednictvím delegáta: centralManagerDidUpdateState(_:). Vývojář musí zpracovat všechny stavy — nejen poweredOn, ale i případy, kdy je Bluetooth vypnutý nebo nedostupný.
| Stav | Význam | Akce vývojáře |
|---|---|---|
| .poweredOn | Bluetooth je zapnutý a připravený | Zahájit skenování |
| .poweredOff | Bluetooth je vypnutý | Zobrazit upozornění uživateli |
| .unauthorized | Bez oprávnění | Požádat o oprávnění v Nastavení |
| .unsupported | Zařízení nepodporuje BLE | Skrýt BLE funkce |
| .unknown | Stav není definován | Počkat na další aktualizaci |
| .resetting | Bluetooth se restartuje | Počkat na obnovení |
Unauthorized state se stává stále častějším od iOS 13+. Od této verze musí mít aplikace oprávnění NSBluetoothAlwaysUsageDescription v Info.plist. Bez něj centrální manažer přejde do stavu .unauthorized a skenování je nemožné. Uživatel může oprávnění kdykoli změnit v Nastavení > Soukromí > Bluetooth.
scanForPeripherals(withServices:options:) — hlavní metoda pro spuštění skenování. Parametr withServices přijímá pole UUID služeb pro filtrování: pokud je předáno nil, budou objevena všechna zařízení, což výrazně zvyšuje spotřebu energie. Doporučuje se vždy filtrovat podle UUID služeb, které aplikace potřebuje. Možnosti skenování zahrnují CBCentralManagerScanOptionAllowDuplicatesKey (opakovaná upozornění o stejném zařízení).
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") // Služba baterie
centralManager.scanForPeripherals(
withServices: [serviceUUID],
options: [
CBCentralManagerScanOptionAllowDuplicatesKey: false
]
)
}
}
Při objevení zařízení je voláno centralManager(_:didDiscover:advertisementData:rssi:). Parametr advertisementData obsahuje úplný slovník dat reklamního paketu, včetně názvu zařízení (CBAdvertisementDataLocalNameKey), UUID služeb (CBAdvertisementDataServiceUUIDsKey) a dat výrobce (CBAdvertisementDataManufacturerDataKey). RSSI — úroveň signálu v dBm, dostupná v okamžiku objevení.
connect(_:options:) — metoda pro navázání BLE připojení s objeveným Peripheral. Po volání connect se iOS pokusí připojit k zařízení. Úspěšné připojení je potvrzeno voláním centralManager(_:didConnect:), chyba voláním centralManager(_:didFailToConnect:error:). Možnosti připojení zahrnují CBConnectPeripheralOptionNotifyOnConnectionKey, CBConnectPeripheralOptionNotifyOnDisconnectionKey a CBConnectPeripheralOptionNotifyOnNotificationKey pro oznámení na pozadí.
// Připojit k BLE zařízení
func connectToPeripheral(
_ peripheral: CBPeripheral
) {
centralManager.connect(peripheral, options: nil)
// Nastavit delegáta pro Peripheral
peripheral.delegate = self
}
// Delegát: úspěšné připojení
func centralManager(
_ central: CBCentralManager,
didConnect peripheral: CBPeripheral
) {
print("Připojeno k " +
"\(peripheral.name ?? "unknown")")
// Spustit objevování služeb
peripheral.discoverServices(nil)
}
// Delegát: chyba připojení
func centralManager(
_ central: CBCentralManager,
didFailToConnect peripheral: CBPeripheral,
error: Error?
) {
print("Connection failed:
\(error?.localizedDescription ?? "")")
}
Časový limit připojení na iOS je 30 sekund. Pokud zařízení během této doby neodpoví na požadavek připojení, je voláno didFailToConnect. Faktory ovlivňující časový limit: vzdálenost k zařízení, rušení, zda zařízení aktuálně inzeruje. Před připojením se ujistěte, že zařízení je v režimu connectable advertising (ADV_IND, ne ADV_NONCONN_IND).
Po připojení je třeba objevit služby (discoverServices) a charakteristiky (discoverCharacteristics) Peripheral. Toto je povinný krok před čtením nebo zápisem dat. Proces je asynchronní: discoverServices vrací výsledek prostřednictvím peripheral(_:didDiscoverServices:), a discoverCharacteristics prostřednictvím peripheral(_:didDiscoverCharacteristicsFor:error:).
Doporučuje se předávat do discoverServices pole zájmových UUID, nikoli nil. Filtrování urychluje objevování a šetří energii. Pokud služba není nalezena, iOS nahlásí prázdné pole. Po objevení charakteristik lze číst jejich hodnoty (readValue), přihlásit se k odběru oznámení (setNotifyValue) nebo zapisovat data (writeValue).
Důležitý detail: MTU je sjednáno automaticky po připojení. Pro získání aktuálního MTU použijte peripheral.maximumWriteValueLength(for: .withResponse) nebo .withoutResponse. V iOS je maximální MTU 512 bajtů pro zařízení s BLE 5.0. Pokud potřebujete přenést data větší než MTU, implementujte fragmentaci na úrovni aplikace.
Skenování na pozadí BLE zařízení na iOS vyžaduje speciální konfiguraci. Core Bluetooth podporuje běh na pozadí, ale s výraznými omezeními. Pro práci na pozadí je nutné: zapnout bluetooth-central v Background Modes v Capabilities projektu, inicializovat CBCentralManager s možností CBCentralManagerOptionRestoreIdentifierKey pro state restoration a zpracovávat události centrálního manažera při přechodu na pozadí.
Omezení BLE na pozadí v iOS: scanForPeripherals bez filtrování podle UUID nefunguje na pozadí. Aplikace musí specifikovat konkrétní UUID služeb pro skenování. iOS může zpozdit doručení BLE událostí na neurčitou dobu. Core Bluetooth automaticky obnoví skenování při objevení odpovídajícího zařízení, i když je aplikace na pozadí. Časový limit skenování na pozadí: iOS může zastavit skenování po 10–30 minutách pro úsporu energie.
State Restoration — mechanismus Core Bluetooth, který umožňuje obnovit BLE připojení po restartu aplikace nebo restartu iOS. Pro použití: zadejte CBCentralManagerOptionRestoreIdentifierKey při inicializaci, implementujte centralManager(_:willRestoreState:) v delegátovi a obnovte seznam připojených Peripheral z předaného slovníku. State Restoration je kritická funkcionalita pro BLE aplikace běžící na pozadí, jako jsou fitness trackery nebo zdravotnická zařízení.
CBCentralManager generuje chyby v několika scénářích: připojení se nezdařilo (didFailToConnect), připojení bylo přerušeno (didDisconnectPeripheral), charakteristika není dostupná pro čtení/zápis (didWriteValue error). Všechny chyby Core Bluetooth jsou vráceny prostřednictvím objektu Error s doménou CBErrorDomain. Nejčastější kódy: CBErrorConnectionTimeout (0x04), CBErrorPeripheralDisconnected (0x07), CBErrorOperationNotSupported (0x0A).
Strategie obnovení připojení: při přijetí didDisconnectPeripheral zkontrolujte kód chyby. Pokud je chyba CBErrorConnectionTimeout nebo CBErrorPeripheralDisconnected — naplánujte automatické opětovné připojení za 1–5 sekund. Pokud je chyba CBErrorOperationNotSupported — zaznamenejte a nepokoušejte se operaci opakovat. Pro kritická připojení (zdravotnická zařízení) použijte exponential backoff s maximálním intervalem 60 sekund.
// Zpracování odpojení s automatickým opětovným připojením
func centralManager(
_ central: CBCentralManager,
didDisconnectPeripheral peripheral: CBPeripheral,
error: Error?
) {
guard let error = error else {
return // Očekávané odpojení
}
print("Disconnected: \(error.localizedDescription)")
// Automatické opětovné připojení
if shouldAutoReconnect {
DispatchQueue.main.asyncAfter(
deadline: .now() + reconnectDelay
) {
central.connect(peripheral)
}
}
}
Při vývoji spolehlivé BLE aplikace na iOS zvažte: Core Bluetooth nezaručuje doručení všech paketů při slabém signálu. Pro spolehlivý přenos použijte writeType .withResponse (potvrzený zápis) a přihlaste se k odběru oznámení (setNotifyValue) pro příjem dat od Peripheral. Veďte záznam chyb pro diagnostiku problémů s připojením v produkci.
Často kladené otázky
Zkontrolujte stav manažera pomocí centralManagerDidUpdateState. Ujistěte se, že oprávnění NSBluetoothAlwaysUsageDescription je v Info.plist, Bluetooth je zapnutý na zařízení a periferní zařízení inzeruje se správným typem (connectable advertising, ne non-connectable).
Na zařízeních s BLE 5.0 (iPhone 8 a novější) — až 7 současných připojení. Na starších zařízeních — až 3–5. Počet skenovaných zařízení je neomezený, ale aktivní připojení mají přísný limit stanovený Bluetooth Controllerem.
Doporučuje se skenovat s filtrem podle UUID a vypnout skenování po nalezení zařízení. Nepřetržité skenování vybíjí baterii: 1 hodina nepřetržitého skenování spotřebuje ~10–15 % baterie iPhone. Používejte časovače a podmínky pro zastavení skenování.
CBCentralManager — pro skenování a připojování k externím BLE zařízením (role Central). CBPeripheralManager — aby vaše iOS zařízení samo fungovalo jako BLE periferie (inzerovalo služby). Jedna instance může být pouze v jedné roli.
Implementujte centralManager(_:didDisconnectPeripheral:error:). Pokud chyba není nil — naplánujte automatické opětovné připojení s exponential backoff (1 s → 2 s → 4 s → 8 s → max 60 s). Pokud je chyba nil — zařízení se odpojilo normálně (např. uživatel stiskl tlačítko na zařízení).
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také