CBCentralManager — ay ang sentral na klase ng Core Bluetooth framework sa iOS na namamahala sa pag-scan, pagkonekta, at pakikipag-ugnayan sa mga BLE peripheral device. Ang Core Bluetooth (iOS 5+, 2011) ay nagbibigay ng mataas na antas ng abstraction sa ibabaw ng BLE stack sa antas ng GATT, na nagtatago ng mga detalye ng Link Layer at HCI mula sa developer. Ginagampanan ng CBCentralManager ang papel na Central: ini-scan nito ang ether sa pamamagitan ng scanForPeripherals, sinisimulan ang koneksyon sa pamamagitan ng connect, natutuklasan ang mga serbisyo sa pamamagitan ng discoverServices, at namamahala ng paglilipat ng data. Ayon sa Apple Developer Documentation (2024), sinusuportahan ng CBCentralManager ang hanggang 7 sabay-sabay na BLE na koneksyon sa mga device na may BLE 5.0.
Mga Pangunahing Punto
CBCentralManager — ay ang pangunahing klase ng Core Bluetooth para sa pagpapatupad ng papel na Central sa BLE architecture sa iOS. Pinamamahalaan nito ang buong lifecycle ng BLE connection: mula sa pag-scan ng mga nag-a-advertise na device hanggang sa paglilipat ng data at pagdiskonekta. Ang CBCentralManager ay gumagana nang asynchronous sa pamamagitan ng delegate na CBCentralManagerDelegate, na nag-aabis sa app tungkol sa mga kaganapan sa Bluetooth stack.
Ang pagsisimula ng CBCentralManager ay nag-uumpisa ng proseso ng state restoration: sinusuri ng manager ang status ng Bluetooth sa device at ibinabalik ang mga nakaraang koneksyon kung ang app ay sarado. Ang proseso ng pagsisimula ay maaaring tumagal ng 50 hanggang 500 ms depende sa status ng Bluetooth. Ang app ay dapat maghintay para sa tawag na centralManagerDidUpdateState bago simulan ang anumang BLE operations.
Ang arkitektura ng Core Bluetooth ay binuo sa pattern na Delegation: Ibinibigay ng CBCentralManager ang paghawak ng kaganapan (pagtuklas ng device, pagkonekta, error) sa protocol na CBCentralManagerDelegate. Para sa pagtatrabaho sa isang partikular na Peripheral, ginagamit ang protocol na CBPeripheralDelegate, na nag-aabis tungkol sa pagtuklas ng mga serbisyo, katangian, at pagtanggap ng data. Ang asynchronous na modelong ito ay nagsisiguro ng hindi pagharang sa UI.
Ang CBCentralManager ay dumadaan sa ilang mga status na tumutukoy kung ang BLE stack ay available para sa trabaho. Ang status ay ipinapadala sa pamamagitan ng delegate: centralManagerDidUpdateState(_:). Ang developer ay dapat humawak ng lahat ng status — hindi lamang poweredOn, kundi pati na rin ang mga kaso kapag ang Bluetooth ay naka-off o hindi available.
| Status | Kahulugan | Aksyon ng developer |
|---|---|---|
| .poweredOn | Ang Bluetooth ay naka-on at handa | Simulan ang pag-scan |
| .poweredOff | Ang Bluetooth ay naka-off | Magpakita ng alert sa user |
| .unauthorized | Walang pahintulot | Humingi ng pahintulot sa Settings |
| .unsupported | Hindi sinusuportahan ng device ang BLE | Itago ang mga BLE function |
| .unknown | Hindi natukoy ang status | Maghintay para sa susunod na update |
| .resetting | Maghintay para sa pagpapanumbalik |
Unauthorized state ay nagiging mas karaniwan simula iOS 13+. Mula sa bersyong ito, ang app ay dapat magkaroon ng pahintulot na NSBluetoothAlwaysUsageDescription sa Info.plist. Kung wala ito, ang central manager ay napupunta sa status na .unauthorized at ang pag-scan ay imposible. Maaaring baguhin ng user ang pahintulot anumang oras sa Settings > Privacy > Bluetooth.
scanForPeripherals(withServices:options:) — ang pangunahing paraan para simulan ang pag-scan. Ang parameter na withServices ay tumatanggap ng array ng UUID ng serbisyo para sa pag-filter: kung ang nil ay ipinadala, lahat ng device ay matutuklasan, na makabuluhang nagpapataas ng konsumo ng enerhiya. Inirerekomenda na laging mag-filter ayon sa UUID ng mga serbisyo na kailangan ng app. Kasama sa mga opsyon sa pag-scan ang CBCentralManagerScanOptionAllowDuplicatesKey (mga paulit-ulit na abiso tungkol sa parehong device).
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") // Serbisyo ng Baterya
centralManager.scanForPeripherals(
withServices: [serviceUUID],
options: [
CBCentralManagerScanOptionAllowDuplicatesKey: false
]
)
}
}
Kapag natuklasan ang isang device, tinatawag ang centralManager(_:didDiscover:advertisementData:rssi:). Ang parameter na advertisementData ay naglalaman ng kumpletong diksyunaryo ng data ng advertisement packet, kabilang ang pangalan ng device (CBAdvertisementDataLocalNameKey), UUID ng serbisyo (CBAdvertisementDataServiceUUIDsKey) at data ng manufacturer (CBAdvertisementDataManufacturerDataKey). RSSI — antas ng signal sa dBm, available sa oras ng pagtuklas.
connect(_:options:) — paraan para magtatag ng BLE connection sa natuklasang Peripheral. Pagkatapos ng tawag na connect, sinusubukan ng iOS na kumonekta sa device. Ang matagumpay na koneksyon ay kinumpirma ng tawag na centralManager(_:didConnect:), error ng centralManager(_:didFailToConnect:error:). Kasama sa mga opsyon sa koneksyon ang CBConnectPeripheralOptionNotifyOnConnectionKey, CBConnectPeripheralOptionNotifyOnDisconnectionKey at CBConnectPeripheralOptionNotifyOnNotificationKey para sa mga background notification.
// Kumonekta sa BLE device
func connectToPeripheral(
_ peripheral: CBPeripheral
) {
centralManager.connect(peripheral, options: nil)
// Itakda ang delegate para sa Peripheral
peripheral.delegate = self
}
// Delegate: matagumpay na koneksyon
func centralManager(
_ central: CBCentralManager,
didConnect peripheral: CBPeripheral
) {
print("Nakakonekta sa " +
"\(peripheral.name ?? "unknown")")
// Simulan ang pagtuklas ng serbisyo
peripheral.discoverServices(nil)
}
// Delegate: error sa koneksyon
func centralManager(
_ central: CBCentralManager,
didFailToConnect peripheral: CBPeripheral,
error: Error?
) {
print("Connection failed:
\(error?.localizedDescription ?? "")")
}
Timeout ng koneksyon sa iOS ay 30 segundo. Kung ang device ay hindi tumugon sa kahilingan ng koneksyon sa oras na ito, tinatawag ang didFailToConnect. Mga salik na nakakaapekto sa timeout: distansya sa device, interference, kung ang device ay kasalukuyang nag-a-advertise. Bago kumonekta, siguraduhin na ang device ay nasa connectable advertising mode (ADV_IND, hindi ADV_NONCONN_IND).
Pagkatapos kumonekta kailangan tuklasin ang mga serbisyo (discoverServices) at katangian (discoverCharacteristics) ng Peripheral. Ito ay isang mandatoryong hakbang bago magbasa o magsulat ng data. Ang proseso ay asynchronous: ang discoverServices ay nagbabalik ng resulta sa pamamagitan ng peripheral(_:didDiscoverServices:), at ang discoverCharacteristics sa pamamagitan ng peripheral(_:didDiscoverCharacteristicsFor:error:).
Inirerekomenda na magpadala ng array ng mga kawili-wiling UUID sa discoverServices, hindi nil. Ang pag-filter ay nagpapabilis ng pagtuklas at nakakatipid ng enerhiya. Kung hindi natagpuan ang serbisyo, mag-uulat ang iOS ng empty array. Pagkatapos matuklasan ang mga katangian, maaaring basahin ang kanilang mga value (readValue), mag-subscribe sa mga notification (setNotifyValue) o magsulat ng data (writeValue).
Mahalagang nuance: Ang MTU ay awtomatikong napag-uusapan pagkatapos ng koneksyon. Para makuha ang kasalukuyang MTU, gamitin ang peripheral.maximumWriteValueLength(for: .withResponse) o .withoutResponse. Sa iOS, ang maximum na MTU ay 512 bytes para sa BLE 5.0 devices. Kung kailangan mong maglipat ng data na mas malaki sa MTU, ipatupad ang fragmentation sa antas ng application.
Pag-scan sa background ng mga BLE device sa iOS ay nangangailangan ng espesyal na configuration. Sinusuportahan ng Core Bluetooth ang background execution, ngunit may makabuluhang limitasyon. Para sa background work, kinakailangan: i-activate ang bluetooth-central sa Background Modes sa Capabilities ng proyekto, i-initialize ang CBCentralManager gamit ang opsyon na CBCentralManagerOptionRestoreIdentifierKey para sa state restoration, at hawakan ang mga kaganapan ng central manager kapag lumipat sa background.
Mga limitasyon ng BLE sa background sa iOS: Ang scanForPeripherals na walang UUID filtering ay hindi gumagana sa background. Dapat tukuyin ng app ang mga partikular na UUID ng serbisyo para sa pag-scan. Maaaring antalahin ng iOS ang paghahatid ng mga BLE event nang walang tiyak na oras. Awtomatikong ipinagpatuloy ng Core Bluetooth ang pag-scan kapag natuklasan ang isang katugmang device, kahit na ang app ay nasa background. Timeout ng pag-scan sa background: Maaaring ihinto ng iOS ang pag-scan pagkatapos ng 10–30 minuto upang makatipid ng enerhiya.
State Restoration — mekanismo ng Core Bluetooth na nagpapahintulot sa pagpapanumbalik ng mga BLE connection pagkatapos i-restart ang app o iOS reboot. Para sa paggamit: tukuyin ang CBCentralManagerOptionRestoreIdentifierKey sa pagsisimula, ipatupad ang centralManager(_:willRestoreState:) sa delegate at ibalik ang listahan ng mga konektadong Peripheral mula sa ipinadalang diksyunaryo. Ang State Restoration ay isang kritikal na functionality para sa mga BLE app na gumagana sa background, tulad ng mga fitness tracker o medical device.
Ang CBCentralManager ay bumubuo ng mga error sa ilang mga sitwasyon: nabigo ang koneksyon (didFailToConnect), naputol ang koneksyon (didDisconnectPeripheral), ang katangian ay hindi available para sa pagbasa/pagsulat (didWriteValue error). Lahat ng Core Bluetooth error ay ibinabalik sa pamamagitan ng Error object na may domain na CBErrorDomain. Ang pinakakaraniwang code: CBErrorConnectionTimeout (0x04), CBErrorPeripheralDisconnected (0x07), CBErrorOperationNotSupported (0x0A).
Estratehiya sa pagpapanumbalik ng koneksyon: kapag natanggap ang didDisconnectPeripheral, suriin ang error code. Kung ang error ay CBErrorConnectionTimeout o CBErrorPeripheralDisconnected — i-iskedyul ang awtomatikong muling pagkonekta pagkatapos ng 1–5 segundo. Kung ang error ay CBErrorOperationNotSupported — i-log at huwag subukang ulitin ang operasyon. Para sa mga kritikal na koneksyon (medical device) gamitin ang exponential backoff na may maximum interval na 60 segundo.
// Pangasiwaan ang pagdiskonekta gamit ang auto-reconnect
func centralManager(
_ central: CBCentralManager,
didDisconnectPeripheral peripheral: CBPeripheral,
error: Error?
) {
guard let error = error else {
return // Inaasahang pagdiskonekta
}
print("Disconnected: \(error.localizedDescription)")
// Awtomatikong muling pagkonekta
if shouldAutoReconnect {
DispatchQueue.main.asyncAfter(
deadline: .now() + reconnectDelay
) {
central.connect(peripheral)
}
}
}
Kapag nag-develop ng maaasahang BLE app sa iOS, isaalang-alang: Hindi ginagarantiyahan ng Core Bluetooth ang paghahatid ng lahat ng packet kapag mahina ang signal. Para sa maaasahang paglilipat, gamitin ang writeType .withResponse (kinumpirmang pagsulat) at mag-subscribe sa mga notification (setNotifyValue) para makatanggap ng data mula sa Peripheral. Magtago ng log ng error para sa pag-diagnose ng mga problema sa koneksyon sa produksyon.
Mga Madalas Itanong
Suriin ang status ng manager sa pamamagitan ng centralManagerDidUpdateState. Siguraduhin na ang pahintulot na NSBluetoothAlwaysUsageDescription ay nasa Info.plist, ang Bluetooth ay naka-on sa device, at ang peripheral device ay nag-a-advertise gamit ang tamang uri (connectable advertising, hindi non-connectable).
Sa mga device na may BLE 5.0 (iPhone 8 at mas bago) — hanggang 7 sabay-sabay na koneksyon. Sa mas lumang device — hanggang 3–5. Ang bilang ng mga na-scan na device ay walang limitasyon, ngunit ang mga aktibong koneksyon ay may mahigpit na limitasyon na itinakda ng Bluetooth Controller.
Inirerekomenda mag-scan gamit ang UUID filter at patayin ang pag-scan kapag natagpuan ang device. Ang patuloy na pag-scan ay nakakaubos ng baterya: 1 oras ng tuloy-tuloy na pag-scan ay kumokonsumo ng ~10–15% ng baterya ng iPhone. Gumamit ng mga timer at kundisyon para ihinto ang pag-scan.
CBCentralManager — para sa pag-scan at pagkonekta sa mga panlabas na BLE device (Central role). CBPeripheralManager — para ang iyong iOS device mismo ay kumilos bilang BLE peripheral (mag-advertise ng mga serbisyo). Ang isang instance ay maaari lamang nasa isang papel.
Ipatupad ang centralManager(_:didDisconnectPeripheral:error:). Kung ang error ay hindi nil — i-iskedyul ang awtomatikong muling pagkonekta gamit ang exponential backoff (1 s → 2 s → 4 s → 8 s → max 60 s). Kung ang error ay nil — ang device ay nadiskonekta nang normal (halimbawa, pinindot ng user ang isang button sa device).
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din