CBCentralManager — a Core Bluetooth keretrendszer központi osztálya iOS-ben, amely a BLE-perifériák szkennelését, csatlakoztatását és az interakciót kezeli. A Core Bluetooth (iOS 5+, 2011) magas szintű absztrakciót biztosít a BLE-verem felett GATT-szinten, elrejtve a fejlesztő elől a Link Layer és HCI részleteit. A CBCentralManager a Central szerepet tölti be: szkenneli az étert a scanForPeripherals segítségével, elindítja a kapcsolatot a connect segítségével, felfedezi a szolgáltatásokat a discoverServices segítségével, és kezeli az adatátvitelt. Az Apple Developer Documentation (2024) szerint a CBCentralManager akár 7 egyidejű BLE-kapcsolatot támogat BLE 5.0-s eszközökön.
Főbb pontok
CBCentralManager — a Core Bluetooth fő osztálya a Central szerep implementálásához a BLE-architektúrában iOS-en. Kezeli a BLE-kapcsolat teljes életciklusát: a reklámozó eszközök szkennelésétől az adatátvitelig és a kapcsolat bontásáig. A CBCentralManager aszinkron módon működik a CBCentralManagerDelegate delegátuson keresztül, értesítve az alkalmazást a Bluetooth-verem eseményeiről.
A CBCentralManager inicializálása elindítja a state restoration folyamatot: a menedzser ellenőrzi a Bluetooth állapotát az eszközön, és visszaállítja az előző kapcsolatokat, ha az alkalmazás be volt zárva. Az inicializálási folyamat 50–500 ms-ig tarthat a Bluetooth állapotától függően. Az alkalmazásnak meg kell várnia a centralManagerDidUpdateState hívást, mielőtt bármilyen BLE-műveletet megkezdene.
A Core Bluetooth architektúrája a Delegation mintára épül: a CBCentralManager az események feldolgozását (eszközök felfedezése, csatlakozás, hibák) a CBCentralManagerDelegate protokollra delegálja. Egy adott Peripheral-lel való munkához a CBPeripheralDelegate protokollt használják, amely értesít a szolgáltatások, jellemzők felfedezéséről és az adatok fogadásáról. Ez az aszinkron modell biztosítja a UI nem blokkoló működését.
A CBCentralManager több állapoton megy keresztül, amelyek meghatározzák, hogy a BLE-verem elérhető-e a munkához. Az állapot a delegátuson keresztül kerül továbbításra: centralManagerDidUpdateState(_:). A fejlesztőnek minden állapotot kezelnie kell — nem csak a poweredOn-t, hanem azokat az eseteket is, amikor a Bluetooth ki van kapcsolva vagy nem elérhető.
| Állapot | Jelentés | Fejlesztői művelet |
|---|---|---|
| .poweredOn | A Bluetooth be van kapcsolva és készen áll | Szkennelés indítása |
| .poweredOff | A Bluetooth ki van kapcsolva | Figyelmeztetés megjelenítése a felhasználónak |
| .unauthorized | Nincs engedély | Engedély kérése a Beállításokban |
| .unsupported | Az eszköz nem támogatja a BLE-t | BLE-funkciók elrejtése |
| .unknown | Az állapot nincs meghatározva | Várjon a következő frissítésre |
| .resetting | A Bluetooth újraindul | Várjon a helyreállításra |
Unauthorized state egyre gyakoribbá válik iOS 13+ óta. Ettől a verziótól kezdve az alkalmazásnak rendelkeznie kell az NSBluetoothAlwaysUsageDescription engedéllyel az Info.plist-ben. Enélkül a központi menedzser .unauthorized állapotba kerül, és a szkennelés lehetetlen. A felhasználó bármikor módosíthatja az engedélyt a Beállítások > Adatvédelem > Bluetooth menüpontban.
scanForPeripherals(withServices:options:) — a fő metódus a szkennelés elindításához. A withServices paraméter a szolgáltatások UUID-jének tömbjét fogadja a szűréshez: ha nil kerül elküldésre, az összes eszköz felfedezésre kerül, ami jelentősen megnöveli az energiafogyasztást. Javasolt mindig szűrni az alkalmazás által igényelt szolgáltatások UUID-je alapján. A szkennelési opciók közé tartozik a CBCentralManagerScanOptionAllowDuplicatesKey (ismétlődő értesítések ugyanarról az eszközről).
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") // Akkumulátor Szolgáltatás
centralManager.scanForPeripherals(
withServices: [serviceUUID],
options: [
CBCentralManagerScanOptionAllowDuplicatesKey: false
]
)
}
}
Egy eszköz felfedezésekor a centralManager(_:didDiscover:advertisementData:rssi:) kerül meghívásra. Az advertisementData paraméter a reklámcsomag adatainak teljes szótárát tartalmazza, beleértve az eszköz nevét (CBAdvertisementDataLocalNameKey), a szolgáltatások UUID-jeit (CBAdvertisementDataServiceUUIDsKey) és a gyártó adatait (CBAdvertisementDataManufacturerDataKey). RSSI — a jel erőssége dBm-ben, a felfedezés pillanatában elérhető.
connect(_:options:) — metódus a BLE-kapcsolat létrehozására a felfedezett Peripheral-lel. A connect meghívása után az iOS megpróbál csatlakozni az eszközhöz. A sikeres csatlakozást a centralManager(_:didConnect:) hívás, a hibát a centralManager(_:didFailToConnect:error:) erősíti meg. A csatlakozási opciók közé tartozik a CBConnectPeripheralOptionNotifyOnConnectionKey, a CBConnectPeripheralOptionNotifyOnDisconnectionKey és a CBConnectPeripheralOptionNotifyOnNotificationKey a háttérértesítésekhez.
// Csatlakozás BLE-eszközhöz
func connectToPeripheral(
_ peripheral: CBPeripheral
) {
centralManager.connect(peripheral, options: nil)
// Delegátus beállítása Peripheral-hez
peripheral.delegate = self
}
// Delegátus: sikeres csatlakozás
func centralManager(
_ central: CBCentralManager,
didConnect peripheral: CBPeripheral
) {
print("Csatlakozva: " +
"\(peripheral.name ?? "unknown")")
// Szolgáltatás felfedezésének indítása
peripheral.discoverServices(nil)
}
// Delegátus: csatlakozási hiba
func centralManager(
_ central: CBCentralManager,
didFailToConnect peripheral: CBPeripheral,
error: Error?
) {
print("Connection failed:
\(error?.localizedDescription ?? "")")
}
A csatlakozás időtúllépése iOS-en 30 másodperc. Ha az eszköz ez idő alatt nem válaszol a csatlakozási kérelemre, a didFailToConnect kerül meghívásra. Az időtúllépést befolyásoló tényezők: távolság az eszköztől, interferencia, hogy az eszköz jelenleg reklámoz-e. Csatlakozás előtt győződjön meg arról, hogy az eszköz connectable advertising módban van (ADV_IND, nem ADV_NONCONN_IND).
Csatlakozás után fel kell fedezni a Peripheral szolgáltatásait (discoverServices) és jellemzőit (discoverCharacteristics). Ez kötelező lépés az adatok olvasása vagy írása előtt. A folyamat aszinkron: a discoverServices az eredményt a peripheral(_:didDiscoverServices:) segítségével, a discoverCharacteristics pedig a peripheral(_:didDiscoverCharacteristicsFor:error:) segítségével adja vissza.
Javasolt a discoverServices számára a nil helyett a kívánt UUID-k tömbjét átadni. A szűrés felgyorsítja a felfedezést és energiát takarít meg. Ha a szolgáltatás nem található, az iOS üres tömböt jelent. A jellemzők felfedezése után lehetőség van azok értékeinek olvasására (readValue), értesítésekre való feliratkozásra (setNotifyValue) vagy adatok írására (writeValue).
Fontos részlet: Az MTU automatikusan megegyezésre kerül a csatlakozás után. Az aktuális MTU lekéréséhez használja a peripheral.maximumWriteValueLength(for: .withResponse) vagy .withoutResponse metódust. iOS-ben a maximális MTU 512 bájt a BLE 5.0-s eszközök számára. Ha az MTU-nál nagyobb adatokat kell átvinnie, implementálja a fragmentációt alkalmazásszinten.
A háttérben történő szkennelés BLE-eszközök iOS-en speciális konfigurációt igényel. A Core Bluetooth támogatja a háttérben történő végrehajtást, de jelentős korlátozásokkal. A háttérben történő munkához szükséges: a bluetooth-central engedélyezése a Background Modes-ban a projekt Capabilities részében, a CBCentralManager inicializálása a CBCentralManagerOptionRestoreIdentifierKey opcióval a state restoration számára, és a központi menedzser eseményeinek kezelése a háttérbe lépéskor.
BLE-korlátozások a háttérben iOS-en: a scanForPeripherals UUID-szűrés nélkül nem működik a háttérben. Az alkalmazásnak meg kell adnia a konkrét szolgáltatás UUID-ket a szkenneléshez. Az iOS határozatlan ideig késleltetheti a BLE-események kézbesítését. A Core Bluetooth automatikusan folytatja a szkennelést, ha egy megfelelő eszközt fedez fel, még akkor is, ha az alkalmazás a háttérben van. A háttérszkennelés időtúllépése: az iOS 10–30 perc után leállíthatja a szkennelést az energia megtakarítása érdekében.
State Restoration — a Core Bluetooth mechanizmusa, amely lehetővé teszi a BLE-kapcsolatok helyreállítását az alkalmazás újraindítása vagy iOS-reboot után. Használatához: adja meg a CBCentralManagerOptionRestoreIdentifierKey-t az inicializáláskor, implementálja a centralManager(_:willRestoreState:) metódust a delegátusban, és állítsa vissza a csatlakoztatott Peripheral-ek listáját a továbbított szótárból. A State Restoration kritikus funkció a háttérben működő BLE-alkalmazások számára, mint például fitneszkövetők vagy orvosi eszközök.
A CBCentralManager hibákat generál több forgatókönyvben: a kapcsolat sikertelen (didFailToConnect), a kapcsolat megszakadt (didDisconnectPeripheral), a jellemző nem elérhető olvasásra/írásra (didWriteValue error). Az összes Core Bluetooth hiba az Error objektumon keresztül kerül visszaadásra a CBErrorDomain doménnel. A leggyakoribb kódok: CBErrorConnectionTimeout (0x04), CBErrorPeripheralDisconnected (0x07), CBErrorOperationNotSupported (0x0A).
Kapcsolat helyreállítási stratégia: a didDisconnectPeripheral fogadásakor ellenőrizze a hibakódot. Ha a hiba CBErrorConnectionTimeout vagy CBErrorPeripheralDisconnected — ütemezzen automatikus újracsatlakozást 1–5 másodperc után. Ha a hiba CBErrorOperationNotSupported — naplózza és ne próbálja megismételni a műveletet. Kritikus kapcsolatok esetén (orvosi eszközök) használjon exponential backoff-ot, maximum 60 másodperces intervallummal.
// Kapcsolat megszakadás kezelése automatikus újracsatlakozással
func centralManager(
_ central: CBCentralManager,
didDisconnectPeripheral peripheral: CBPeripheral,
error: Error?
) {
guard let error = error else {
return // Várható kapcsolatbontás
}
print("Disconnected: \(error.localizedDescription)")
// Automatikus újracsatlakozás
if shouldAutoReconnect {
DispatchQueue.main.asyncAfter(
deadline: .now() + reconnectDelay
) {
central.connect(peripheral)
}
}
}
Megbízható BLE-alkalmazás fejlesztésekor iOS-en vegye figyelembe: a Core Bluetooth nem garantálja az összes csomag kézbesítését gyenge jel esetén. A megbízható átvitelhez használja a writeType .withResponse-t (megerősített írás), és iratkozzon fel az értesítésekre (setNotifyValue) az adatok fogadásához a Peripheral-től. Vezessen hiba naplót a kapcsolati problémák diagnosztizálásához éles környezetben.
Gyakran Ismételt Kérdések
Ellenőrizze a menedzser állapotát a centralManagerDidUpdateState segítségével. Győződjön meg arról, hogy az NSBluetoothAlwaysUsageDescription engedély szerepel az Info.plist-ben, a Bluetooth be van kapcsolva az eszközön, és a periféria eszköz a megfelelő típussal reklámoz (connectable advertising, nem non-connectable).
BLE 5.0-s eszközökön (iPhone 8 és újabb) — akár 7 egyidejű kapcsolat. Régebbi eszközökön — akár 3–5. A szkennelt eszközök száma korlátlan, de az aktív kapcsolatoknak szigorú korlátja van, amelyet a Bluetooth Controller állít be.
Javasolt UUID-szűrővel szkennelni és kikapcsolni a szkennelést, amikor az eszköz megtalálásra került. A folyamatos szkennelés lemeríti az akkumulátort: 1 óra folyamatos szkennelés ~10–15%-ot fogyaszt az iPhone akkumulátorából. Használjon időzítőket és feltételeket a szkennelés leállításához.
CBCentralManager — külső BLE-eszközök szkennelésére és csatlakoztatására (Central szerep). CBPeripheralManager — hogy az iOS-eszköz maga BLE-perifériaként működjön (szolgáltatásokat reklámozzon). Egy példány csak egy szerepben lehet.
Implementálja a centralManager(_:didDisconnectPeripheral:error:) metódust. Ha a hiba nem nil — ütemezzen automatikus újracsatlakozást exponential backoff-fal (1 s → 2 s → 4 s → 8 s → max 60 s). Ha a hiba nil — az eszköz normál módon kapcsolódott le (pl. a felhasználó megnyomott egy gombot az eszközön).
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is