CBCentralManager — је централна класа оквира Core Bluetooth у iOS-у која управља скенирањем, повезивањем и интеракцијом са BLE периферијским уређајима. Core Bluetooth (iOS 5+, 2011) пружа високонивоапстракцију изнад BLE стека на нивоу GATT, сакривајући од програмера детаље Link Layer и HCI. CBCentralManager остварује улогу Central: скенира етар путем scanForPeripherals, покреће повезивање путем connect, открива сервисе путем discoverServices и управља преносом података. Према Apple Developer Documentation (2024), CBCentralManager подржава до 7 истовремених BLE веза на уређајима са BLE 5.0.
Главно
CBCentralManager — је главна класа Core Bluetooth за имплементацију улоге Central у BLE архитектури на iOS-у. Управља целокупним животним циклусом BLE везе: од скенирања уређаја који се рекламирају до преноса података и прекида везе. CBCentralManager ради асинхроно путем делегата CBCentralManagerDelegate, обавештавајући апликацију о догађајима у Bluetooth стеку.
Иницијализација CBCentralManager покреће процес state restoration: менаџер проверава стање Bluetooth-а на уређају и обнавља претходне везе ако је апликација била затворена. Процес иницијализације може да траје од 50 до 500 мс у зависности од стања Bluetooth-а. Апликација мора да сачека позив centralManagerDidUpdateState пре почетка било којих BLE операција.
Архитектура Core Bluetooth изграђена је на обрасцу Delegation: CBCentralManager делегира обраду догађаја (откривање уређаја, повезивање, грешке) протоколу CBCentralManagerDelegate. За рад са одређеним Peripheral-ом користи се протокол CBPeripheralDelegate који обавештава о откривању сервиса, карактеристика и пријему података. Оває асинхрони модел осигурава неблокирајући рад UI-ја.
CBCentralManager пролази кроз неколико стања која одређују да ли је BLE стек доступан за рад. Стање се преноси путем делегата: centralManagerDidUpdateState(_:). Програмер је дужан да обради сва стања — не само poweredOn, већ и случајеве када је Bluetooth искључен или недоступан.
| Стање | Значење | Акција програмера |
|---|---|---|
| .poweredOn | Bluetooth је укључен и спреман | Почни скенирање |
| .poweredOff | Bluetooth је искључен | Прикажи упозорење кориснику |
| .unauthorized | Нема дозволе | Затражи дозволу у Поставкама |
| .unsupported | Уређај не подржава BLE | Сакриј BLE функције |
| .unknown | Стање није дефинисано | Чекај следеће ажурирање |
| .resetting | Bluetooth се поново покреће | Чекај опоравак |
Unauthorized state постаје све чешће од iOS 13+. Почевши од ове верзије, апликација мора да има дозволу NSBluetoothAlwaysUsageDescription у Info.plist. Без ње, централни менаџер прелази у стање .unauthorized и скенирање је немогуће. Корисник може да промени дозволу у сваком тренутку у Settings > Privacy > Bluetooth.
scanForPeripherals(withServices:options:) — главна метода за покретање скенирања. Параметар withServices прима низ UUID сервиса за филтрирање: ако се проследи nil, биће откривени сви уређаји, што значајно повећава потрошњу енергије. Препоручује се увијек филтрирати по UUID сервиса који су потребни апликацији. Опције скенирања укључују CBCentralManagerScanOptionAllowDuplicatesKey (поновна обавештавања о истом уређају).
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") // Сервис батерије
centralManager.scanForPeripherals(
withServices: [serviceUUID],
options: [
CBCentralManagerScanOptionAllowDuplicatesKey: false
]
)
}
}
При откривању уређаја позива се centralManager(_:didDiscover:advertisementData:rssi:). Параметар advertisementData садржи пун речник података рекламног пакета, укључујући име уређаја (CBAdvertisementDataLocalNameKey), UUID сервиса (CBAdvertisementDataServiceUUIDsKey) и податке произвођача (CBAdvertisementDataManufacturerDataKey). RSSI — ниво сигнала у dBm, доступан у тренутку откривања.
connect(_:options:) — метода за успостављање BLE везе са откривеним Peripheral-ом. Након позива connect, iOS покушава да се повеже са уређајем. Успешно повезивање потврђује се позивом centralManager(_:didConnect:), грешка — centralManager(_:didFailToConnect:error:). Опције повезивања укључују CBConnectPeripheralOptionNotifyOnConnectionKey, CBConnectPeripheralOptionNotifyOnDisconnectionKey и CBConnectPeripheralOptionNotifyOnNotificationKey за позадинска обавештавања.
// Повежи се на BLE уређај
func connectToPeripheral(
_ peripheral: CBPeripheral
) {
centralManager.connect(peripheral, options: nil)
// Постави делегата за Peripheral
peripheral.delegate = self
}
// Делегат: успешно повезивање
func centralManager(
_ central: CBCentralManager,
didConnect peripheral: CBPeripheral
) {
print("Повезан на " +
"\(peripheral.name ?? "unknown")")
// Почни откривање сервиса
peripheral.discoverServices(nil)
}
// Делегат: грешка повезивања
func centralManager(
_ central: CBCentralManager,
didFailToConnect peripheral: CBPeripheral,
error: Error?
) {
print("Connection failed:
\(error?.localizedDescription ?? "")")
}
Прекид повезивања на iOS-у износи 30 секунди. Ако уређај не одговори на захтев за повезивање у овом року, позива се didFailToConnect. На прекид утичу: удаљеност до уређаја, сметње, да ли се уређај тренутно рекламира. Пре повезивања уверите се да је уређај у режиму connectable advertising (ADV_IND, а не ADV_NONCONN_IND).
Након повезивања потребно је открити сервисе (discoverServices) и карактеристике (discoverCharacteristics) Peripheral-а. Ово је обавезан корак пре читања или уписивања података. Процес је асинхрон: discoverServices враћа резултат путем peripheral(_:didDiscoverServices:), а discoverCharacteristics — путем peripheral(_:didDiscoverCharacteristicsFor:error:).
Препоручује се да у discoverServices проследите низ занимљивих UUID, а не nil. Филтрирање убрзава откривање и штеди енергију. Ако сервис није пронађен, iOS ће пријавити празан низ. Након откривања карактеристика, можете читати њихове вредности (readValue), претплатити се на обавештавања (setNotifyValue) или уписивати податке (writeValue).
Важан детаљ: MTU се договара аутоматски након повезивања. За добијање тренутног MTU-а користите peripheral.maximumWriteValueLength(for: .withResponse) или .withoutResponse. У iOS-у максимални MTU је 512 бајтова за BLE 5.0 уређаје. Ако треба да пренесете податке веће од MTU-а, имплементирајте фрагментацију на нивоу апликације.
Скенирање у позадини BLE уређаја на iOS-у захтева посебну конфигурацију. Core Bluetooth подржава извршавање у позадини, али са значајним ограничењима. За рад у позадини потребно је: укључити bluetooth-central у Background Modes у Capabilities пројекта, иницијализовати CBCentralManager са опцијом CBCentralManagerOptionRestoreIdentifierKey за state restoration и обрађивати догађаје централног менаџера при преласку у позадину.
Ограничења BLE-а у позадини у iOS-у: scanForPeripherals без филтрирања по UUID-у не ради у позадини. Апликација мора да наведе конкретне UUID сервиса за скенирање. iOS може да одложи испоруку BLE догађаја на неодређено време. Core Bluetooth аутоматски наставља скенирање при откривању одговарајућег уређаја, чак и ако је апликација у позадини. Прекид скенирања у позадини: iOS може да заустави скенирање након 10–30 минута ради штеде енергије.
State Restoration — механизам Core Bluetooth који омогућава обнављање BLE веза након поновног покретања апликације или поновног покретања iOS-а. За његово коришћење: наведите CBCentralManagerOptionRestoreIdentifierKey при иницијализацији, имплементирајте centralManager(_:willRestoreState:) у делегату и обновите листу повезаних Peripheral-а из прослеђеног речника. State Restoration је критична функционалност за BLE апликације које раде у позадини, као што су фитнес трекери или медицински уређаји.
CBCentralManager генерише грешке у неколико сценарија: повезивање није успело (didFailToConnect), веза је прекинута (didDisconnectPeripheral), карактеристика је недоступна за читање/уписивање (didWriteValue error). Све Core Bluetooth грешке се враћају путем објекта Error са доменом CBErrorDomain. Најчешћи кодови: CBErrorConnectionTimeout (0x04), CBErrorPeripheralDisconnected (0x07), CBErrorOperationNotSupported (0x0A).
Стратегија опоравка везе: при пријему didDisconnectPeripheral проверите код грешке. Ако је грешка CBErrorConnectionTimeout или CBErrorPeripheralDisconnected — закажите аутоматско поновно повезивање након 1–5 секунди. Ако је грешка CBErrorOperationNotSupported — забележите и не покушавајте да поновите операцију. За критичне везе (медицински уређаји) користите exponential backoff са максималним интервалом од 60 секунди.
// Руковање прекидом са аутоматским поновним повезивањем
func centralManager(
_ central: CBCentralManager,
didDisconnectPeripheral peripheral: CBPeripheral,
error: Error?
) {
guard let error = error else {
return // Очекивани прекид
}
print("Disconnected: \(error.localizedDescription)")
// Аутоматско поновно повезивање
if shouldAutoReconnect {
DispatchQueue.main.asyncAfter(
deadline: .now() + reconnectDelay
) {
central.connect(peripheral)
}
}
}
При развоју поуздане BLE апликације на iOS-у узмите у обзир: Core Bluetooth не гарантује испоруку свих пакета при слабом сигналу. За поуздан пренос користите writeType .withResponse (потврђѐен упис) и претплатите се на обавештавања (setNotifyValue) за пријем података од Peripheral-а. Водите евиденцију грешака за дијагностику проблема са везом у производњи.
Често постављана питања
Проверите стање менаџера путем centralManagerDidUpdateState. Уверите се да дозвола NSBluetoothAlwaysUsageDescription постоји у Info.plist, Bluetooth је укључен на уређају и периферијски уређај се рекламира са исправним типом (connectable advertising, а не non-connectable).
На уређајима са BLE 5.0 (iPhone 8 и новији) — до 7 истовремених веза. На старијим уређајима — до 3–5. Број скенираних уређаја је неограничен, али активне везе имају чврсту границу коју поставља Bluetooth Controller.
Препоручује се скенирање са филтром по UUID-у и искључивање скенирања када се уређај пронађе. Непрекидно скенирање празни батерију: 1 сат непрекидног скенирања троши око ~10–15% напуна iPhone-а. Користите тајмере и услове за заустављање скенирања.
CBCentralManager — за скенирање и повезивање са спољашњим BLE уређајима (улога Central). CBPeripheralManager — да би ваш iOS уређај сам деловао као BLE периферија (рекламирао сервисе). Једна инстанца може бити само у једној улози.
Имплементирајте centralManager(_:didDisconnectPeripheral:error:). Ако грешка није nil — закажите аутоматско поновно повезивање са exponential backoff (1 с → 2 с → 4 с → 8 с → макс 60 с). Ако је грешка nil — уређај се искључио редовно (нпр. корисник је притиснуо дугме на уређају).
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође