CBPeripheral — a Core Bluetooth keretrendszer osztálya, amely egy távoli BLE-eszközt képvisel iOS-ben. Minden CBPeripheral objektum magába foglalja az UUID-t, nevet, RSSI-t és a csatlakoztatott BLE-eszköz GATT-szolgáltatásainak hierarchiáját. A fejlesztő kizárólag a CBPeripheral-en keresztül lép kapcsolatba a perifériával: szolgáltatások felderítése (discoverServices:), jellemzők olvasása (readValueForCharacteristic:), adatok írása (writeValue:forCharacteristic:type:) és értesítésekre való feliratkozás (setNotifyValue:forCharacteristic:). A Apple Developer, 2026 szerint a CBPeripheral — a központi objektum az összes BLE-perifériával végzett művelethez, amelyet a CBCentralManager ad vissza az eszköz észlelésekor vagy csatlakozásakor.
Főbb pontok
CBPeripheral — egy objektum, amely egy távoli BLE-eszközt képvisel egy iOS alkalmazásban. Ellentétben a CBCentralManager-rel, amely az iPhone helyi Bluetooth-adapterét kezeli, a CBPeripheral egy külső perifériás eszközt modellez: érzékelő, fitneszkövető, jeladó, orvosi eszköz. Minden CBPeripheral példány egy egyedi azonosítót (UUID) tartalmaz, amely a kapcsolódási munkamenetek között megmarad — az Apple az UUID-t egy adott eszközhöz köti a rendszer Bonding segítségével.
A CBPeripheral nem közvetlenül az init-en keresztül jön létre. A Core Bluetooth keretrendszer két forgatókönyvben ad vissza CBPeripheral objektumot: az eszköz észlelésekor a scanForPeripheralsWithServices: segítségével (delegate didDiscoverPeripheral) és egy korábban ismert eszközhöz való csatlakozáskor a retrievePeripheralsWithIdentifiers: segítségével. Az objektum átvétele után a fejlesztő meghívja a connectPeripheral: metódust a CBCentralManager-en, amely után a CBPeripheral elérhetővé válik GATT-műveletekhez.
A CBPeripheral életciklusa hat állapotot foglal magában: disconnected (kezdeti), connecting (a connect hívása után), connected (a didConnectPeripheral után), discovering (a discoverServices hívása közben), discovered (a szolgáltatások megérkezése után) és disconnecting (a cancelPeripheralConnection után). Minden állapot a CBPeripheralDelegate delegate-en keresztül követhető — kötelező protokoll minden BLE alkalmazáshoz iOS-ben.
CBPeripheral egy hierarchikus GATT-struktúrát tárol, amely három szintből áll. A gyökérszint — CBService tömb (szolgáltatások), minden szolgáltatás CBCharacteristic tömböt (jellemzők), minden jellemző CBDescriptor tömböt (leírók) tartalmaz. Ez a modell teljes mértékben megfelel a Bluetooth GATT specifikációnak: szolgáltatás — az eszköz funkciója (például „Heart Rate Service“), jellemző — konkrét érték (pulzus 72 bpm), leíró — a jellemző metaadatai (mértékegységek, értesítések konfigurációja).
| Szint | Core Bluetooth osztály | Leírás |
|---|---|---|
| Szolgáltatás | CBService | Rokon jellemzők logikai csoportja, UUID (16-bit, 32-bit vagy 128-bit) által azonosítva |
| Jellemző | CBCharacteristic | Konkrét adatérték, támogatja az olvasást, írást, értesítést |
| Leíró | CBDescriptor | A jellemző metaadatai: CCCD kliens konfiguráció, User Description, Presentation Format |
A szabványos BLE-szolgáltatások a Bluetooth SIG-nél vannak regisztrálva: Heart Rate Service (UUID 180D), Battery Service (180F), Device Information (180A), Blood Pressure (1810). Egyedi szolgáltatásokhoz 128 bites UUID-ket használnak (például E20A39F4-73F5-4BC4-A12F-17D1AD07A961). Az iOS automatikusan felismeri a szabványos UUID-ket és ember által olvasható neveket jelenít meg; az egyedi UUID-k hex formátumban jelennek meg.
Csatlakozás után a CBPeripheral hierarchiája üres — a szolgáltatások és jellemzők nincsenek betöltve. A fejlesztőnek meg kell hívnia a discoverServices: metódust a szolgáltatások megszerzéséhez, majd minden szolgáltatáshoz a discoverCharacteristics:forService: metódust. Ha a szolgáltatás tartalmazott szolgáltatásokat (includedServices) tartalmaz, akkor a discoverIncludedServices:forService: is meghívásra kerül. Csak a hierarchia felderítésének befejezése után töltődik fel a CBPeripheral és válik elérhetővé olvasásra és írásra.
Felderítés (discovery) a CBPeripheral GATT-struktúrájának — kötelező lépés bármilyen olvasási vagy írási művelet előtt. A discoverServices: metódus elindítja az eszköz összes szolgáltatásának aszinkron keresését. Ha nil kerül átadásra, minden szolgáltatás felderítésre kerül; ha CBUUID tömb kerül átadásra — csak a megadott UUID-vel rendelkező szolgáltatások (időoptimalizálás). Az eredmény a peripheral:didDiscoverServices: delegate-be érkezik — a CBPeripheral objektum kitölti a services tulajdonságot egy CBService tömbbel.
A szolgáltatások megérkezése után minden CBService-hez meg kell hívni a discoverCharacteristics:forService: metódust. Hasonlóan, nil — minden jellemző, CBUUID tömb — csak a megadottak. Eredmény: peripheral:didDiscoverCharacteristicsForService:error:. Ebben a fázisban a CBCharacteristic tulajdonságokat kap (properties: .read, .write, .notify, .indicate), amelyek meghatározzák az engedélyezett műveleteket.
import CoreBluetooth
extension BLEViewController: CBPeripheralDelegate {
// 1. Szolgáltatás felderítése
func peripheral(_ peripheral: CBPeripheral,
didDiscoverServices error: Error?) {
guard let services = peripheral.services else { return }
for service in services {
// Jellemzők kérése minden szolgáltatáshoz
peripheral.discoverCharacteristics(nil, for: service)
}
}
// 2. Jellemző felderítése
func peripheral(_ peripheral: CBPeripheral,
didDiscoverCharacteristicsFor service: CBService,
error: Error?) {
guard let characteristics = service.characteristics else { return }
for characteristic in characteristics {
if characteristic.properties.contains(.read) {
peripheral.readValue(for: characteristic)
}
if characteristic.properties.contains(.notify) {
peripheral.setNotifyValue(true, for: characteristic)
}
}
}
// 3. Érték olvasása
func peripheral(_ peripheral: CBPeripheral,
didUpdateValueFor characteristic: CBCharacteristic,
error: Error?) {
guard let data = characteristic.value,
let value = String(data: data, encoding: .utf8)
else { return }
print("Characteristic value: \(value)")
}
}
A példában a CBPeripheralDelegate három kötelező felderítési metódusa van implementálva. A didDiscoverServices végigjárja az összes megtalált szolgáltatást és jellemzőket kér. A didDiscoverCharacteristicsForService ellenőrzi az egyes jellemzők tulajdonságait: .read esetén meghívja a readValue-t, .notify esetén a setNotifyValue(true)-t. A didUpdateValueForCharacteristic metódus megkapja az aktuális értéket Data formátumban.
Értékek olvasása CBCharacteristic esetén a readValueForCharacteristic: metódussal történik. Az eredmény aszinkron módon érkezik a peripheral:didUpdateValueForCharacteristic:error:-ban. Fontos: az eszköznek lehet gyorsítótárazott értéke (a characteristic.value közvetlenül a felderítés után elérhető), de az aktuális érték megszerzéséhez a readValue hívása kötelező. Az iOS gyorsítótárazhatja az értékeket az energiahatékonyság érdekében — a readValue frissíti a gyorsítótárat.
Értékek írása a writeValue:forCharacteristic:type: metódussal történik. A type paraméter határozza meg az írás típusát: .withResponse (CBCharacteristicWriteWithResponse) — az eszköz megerősíti az írást a didWriteValueForCharacteristic-en keresztül; .withoutResponse (CBCharacteristicWriteWithoutResponse) — írás megerősítés nélkül, maximális sebesség, de szállítási garancia nélkül. A BLE specifikáció korlátozza az MTU-t (Maximum Transmission Unit): 23 bájtig BLE 4.0 esetén, 251 bájtig BLE 5.0+ esetén. Az MTU-nál nagyobb adatokhoz alkalmazásszintű fragmentáció szükséges.
// CBPeripheral jellemző olvasása és írása
class BLEService {
private let peripheral: CBPeripheral
private let serviceUUID = CBUUID(string: "180D")
private let charUUID = CBUUID(string: "2A37")
init(peripheral: CBPeripheral) {
self.peripheral = peripheral
}
// Olvasás megerősítéssel
func readHeartRate() {
guard let service = peripheral.services?.first(where: { $0.uuid == serviceUUID }),
let characteristic = service.characteristics?.first(where: { $0.uuid == charUUID })
else { return }
peripheral.readValue(for: characteristic)
}
// Írás megerősítéssel (withResponse)
func writeWithResponse(data: Data) {
guard let characteristic = findCharacteristic() else { return }
peripheral.writeValue(data, for: characteristic,
type: .withResponse)
}
// Írás megerősítés nélkül (withoutResponse)
// Maximális átvitel, szállítási garancia nélkül
func writeWithoutResponse(data: Data) {
guard let characteristic = findCharacteristic() else { return }
peripheral.writeValue(data, for: characteristic,
type: .withoutResponse)
}
private func findCharacteristic() -> CBCharacteristic? {
return peripheral.services?
.flatMap { $0.characteristics ?? [] }
.first(where: { $0.uuid == charUUID })
}
}
Az írás típusának kiválasztása withResponse vagy withoutResponse a megbízhatósági követelményektől függ. Parancsokhoz (lámpa bekapcsolása, zár kinyitása) használja a withResponse-t — a szállítás garanciája kritikus. Folyamatos adatokhoz (pulzus, hőmérséklet) használja a withoutResponse-t — egy csomag elvesztése nem jelentős. A BLE-eszköz csak egy írási típust támogathat — ellenőrizze a characteristic.properties.contains(.write) és .writeWithoutResponse tulajdonságot.
Értesítések (notifications) — BLE mechanizmus, amelyben a perifériás eszköz aszinkron módon küldi el a jellemző értékét a központi eszköznek, a központi részről történő állandó polling nélkül. A CBPeripheral a setNotifyValue:forCharacteristic: metódussal aktiválja a feliratkozást. A feliratkozás aktiválása után az iOS automatikusan kiírja a CCCD-t (Client Characteristic Configuration Descriptor) a perifériára, és az eszköz minden értékváltozáskor frissítéseket kezd küldeni.
Az indikációkkal (indicate) ellentétben az értesítések nem igényelnek megerősítést a központitól — a csomag elküldésre kerül és elfelejtődik. Ez maximális sávszélességet biztosít, de csomagvesztés lehetséges. Az indikációk protokoll szinten (L2CAP) igényelnek megerősítést — megbízhatóbbak, de lassabbak. A CBCharacteristic a properties tulajdonságon keresztül pontosan jelzi, melyik módot támogatja: .notify, .indicate vagy mindkettőt.
A CBPeripheral megszakításakor (disconnect, hatókörön kívülre kerülés) az összes aktív feliratkozás automatikusan visszaállításra kerül. Újracsatlakozáskor minden jellemzőhöz újra meg kell hívni a setNotifyValue:true metódust. Az iOS a feliratkozásokat is elveszíti, amikor az alkalmazás kilép az előtérből (ha a háttérmód nincs engedélyezve) — háttérmunkához engedélyezni kell a „Uses Bluetooth LE accessories“ képességet az Info.plist-ben.
// CBPeripheral értesítési feliratkozás kezelése
class NotificationManager: NSObject {
private var peripheral: CBPeripheral?
private var subscribedCharacteristics: Set<CBUUID> = []
// Feliratkozás értesítésekre az összes .notify jellemzőhöz
func subscribeToAllNotifications(peripheral: CBPeripheral) {
self.peripheral = peripheral
guard let services = peripheral.services else { return }
for service in services {
guard let characteristics = service.characteristics else { continue }
for characteristic in characteristics {
if characteristic.properties.contains(.notify)
|| characteristic.properties.contains(.indicate) {
peripheral.setNotifyValue(true, for: characteristic)
subscribedCharacteristics.insert(characteristic.uuid)
}
}
}
}
// Leiratkozás az összes értesítésről
func unsubscribeFromAll() {
guard let peripheral = peripheral else { return }
guard let services = peripheral.services else { return }
for service in services {
guard let characteristics = service.characteristics else { continue }
for characteristic in characteristics {
if subscribedCharacteristics.contains(characteristic.uuid) {
peripheral.setNotifyValue(false, for: characteristic)
}
}
}
subscribedCharacteristics.removeAll()
}
// Értesítéskezelő
func peripheral(_ peripheral: CBPeripheral,
didUpdateNotificationStateFor characteristic: CBCharacteristic,
error: Error?) {
if characteristic.isNotifying {
print("Subscription active: \(characteristic.uuid)")
} else {
print("Subscription inactive: \(characteristic.uuid)")
}
}
}
A NotificationManager feliratkozás-kezelő bemutatja a CBPeripheral értesítésekkel való helyes munkát. A subscribeToAllNotifications végigjárja az összes szolgáltatást és jellemzőt, aktiválva a .notify és .indicate tulajdonságokat. A subscribedCharacteristics nyomon követi az aktív feliratkozásokat a helyes leiratkozáshoz. A didUpdateNotificationStateForCharacteristic megerősíti a feliratkozási állapot sikeres megváltoztatását a characteristic.isNotifying tulajdonságon keresztül.
Teljes munkaciklus a CBPeripheral-lel magában foglalja: az objektum fogadását a CBCentralManager-től, csatlakozást, felderítést, olvasást/írást, feliratkozást az értesítésekre és a kapcsolat bontását. Az alábbi példában a BLEConnection osztály van implementálva, amely a BLE-periféria teljes életciklusát kezeli Swift-ben a modern async/await API (iOS 15+) segítségével.
import CoreBluetooth
// Teljes CBPeripheral kezelési példa async/await segítségével
class BLEConnection: NSObject {
private let centralManager: CBCentralManager
private var peripheral: CBPeripheral?
private var continuation: CheckedContinuation<Void, Error>?
override init() {
centralManager = CBCentralManager(delegate: nil, queue: .main)
super.init()
centralManager.delegate = self
}
// 1. Csatlakozás a perifériához
func connect(to peripheral: CBPeripheral) async throws {
self.peripheral = peripheral
peripheral.delegate = self
centralManager.connect(peripheral, options: nil)
try await withCheckedThrowingContinuation { continuation in
self.continuation = continuation
}
}
// 2. Felderítés
func discoverServices() async throws {
guard let peripheral = peripheral else {
throw BLEError.notConnected
}
peripheral.discoverServices(nil)
try await withCheckedThrowingContinuation { continuation in
self.continuation = continuation
}
}
}
// 3. CBCentralManager
extension BLEConnection: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
// Bluetooth-eszköz állapotának kezelése
}
func centralManager(_ central: CBCentralManager,
didConnect peripheral: CBPeripheral) {
continuation?.resume()
continuation = nil
}
func centralManager(_ central: CBCentralManager,
didFailToConnect peripheral: CBPeripheral,
error: Error?) {
continuation?.resume(throwing: error ?? BLEError.connectionFailed)
continuation = nil
}
}
enum BLEError: Error {
case notConnected
case connectionFailed
case serviceNotFound
case characteristicNotFound
}
A BLEConnection osztály a Swift Concurrency (async/await) funkciót használja a CheckedContinuation segítségével — ez egy modern minta a Core Bluetooth delegate API-ival való munkához. A connect(to:) a csatlakozás megerősítésére vár a didConnectPeripheral-en keresztül, a discoverServices() — a didDiscoverServices-en keresztül. Ez a megközelítés kiküszöböli a beágyazott delegate-eket, és a BLE kódot lineárissá és olvashatóvá teszi. A BLEError-on keresztüli hibakezelés lefedi a BLE-kapcsolat összes tipikus meghibásodási forgatókönyvét.
Gyakran Ismételt Kérdések
A CBPeripheral egy korábban csatlakoztatott eszközhöz a retrievePeripheralsWithIdentifiers: segítségével szerezhető meg a CBCentralManager-en. Adjon át egy UUID (NSUUID) tömböt a korábban mentett eszközökről — a keretrendszer visszaad egy CBPeripheral tömböt a rendszer BLE-bonding adatbázisában lévő eszközökhöz. Ez csak azokkal az eszközökkel működik, amelyekkel az iPhone korábban párosítva volt. Új eszközhöz a szkennelés kötelező.
Fő okok: az eszköz hatókörön kívül van (RSSI a küszöbérték alatt), a BLE rádió ki van kapcsolva (CBCentralManager.state != .poweredOn), a CBPeripheralDelegate delegát nincs beállítva (peripheral.delegate = self), vagy a discoverServices hívása a csatlakozás előtt történt. Ellenőrizze a centralManager.state állapotát, győződjön meg arról, hogy a delegát be van állítva a connect hívása előtt, és használja az újrapróbálkozást 5–10 másodperces időkorláttal.
Ok — a .withResponse használata olyan jellemzőn, amely csak a .writeWithoutResponse-t támogatja, vagy fordítva. Ellenőrizze a characteristic.properties-t a hívás előtt. MTU probléma is lehet: ha az adat > 20 bájt (BLE 4.0 MTU), MTU-egyeztetés szükséges a negotiateMTU vagy fragmentáció segítségével. Használja a peripheral.maximumWriteValueLength(for: .withResponse) metódust a maximális csomagméret meghatározásához.
A hatókörön kívüli CBPeripheral nem szakad meg azonnal — az iOS időtúllépésen keresztül (általában 20–30 másodperc) áthelyezi a .disconnected állapotba. Figyeléshez használja a readRSSI-t a CBPeripheral-en — elérhetetlenség esetén hibát ad vissza a CBError.connectionTimeout kóddal. Kövesse nyomon a centralManager:didDisconnectPeripheral:error: metódust is a kapcsolat megszakadásának időben történő észleléséhez.
A Core Bluetooth nem szálbiztos — az összes CBPeripheral hívást egyetlen sorból kell végrehajtani (általában main queue vagy a CBCentralManager inicializálásakor megadott soros serial queue). A különböző szálakból történő egyidejű hívások versenyhelyzethez és az alkalmazás összeomlásához vezetnek. Használja a DispatchQueue(label: „com.app.ble“) sorokat az összes BLE-művelethez és a DispatchQueue.main.async-et a UI frissítéséhez.
Összefoglaló
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