CBPeripheral — iOS-da uzaq BLE cihazını təmsil edən Core Bluetooth framework sinfi. Hər CBPeripheral obyekti UUID, ad, RSSI və qoşulmuş BLE cihazının GATT servis iyerarxiyasını inkapsulyasiya edir. Developer periferiya ilə yalnız CBPeripheral vasitəsilə qarşılıqlı əlaqə qurur: servislərin discovery-si (discoverServices:), xarakteristikaların oxunması (readValueForCharacteristic:), məlumatların yazılması (writeValue:forCharacteristic:type:) və bildirişlərə abunə olma (setNotifyValue:forCharacteristic:). Apple Developer, 2026-ya görə, CBPeripheral — CBCentralManager tərəfindən cihaz aşkar edildikdə və ya qoşulduqda qaytarılan, BLE-periferiya ilə bütün əməliyyatlar üçün mərkəzi obyektdir.
Əsas məqamlar
CBPeripheral — iOS tətbiqində uzaq BLE cihazını təmsil edən obyektdir. iPhone-un lokal Bluetooth adapterini idarə edən CBCentralManager-dən fərqli olaraq, CBPeripheral xarici periferik cihazı modelləşdirir: sensor, fitnes treker, mayak, tibbi cihaz. Hər CBPeripheral nümunəsi unikal identifikator (UUID) ehtiva edir ki, bu da qoşulma seansları arasında saxlanılır — Apple UUID-ni sistem Bonding vasitəsilə konkret cihazla əlaqələndirir.
CBPeripheral birbaşa init vasitəsilə yaradılmır. Core Bluetooth framework-i CBPeripheral obyektini iki ssenaridə qaytarır: scanForPeripheralsWithServices: vasitəsilə cihaz aşkar edildikdə (delegat didDiscoverPeripheral) və retrievePeripheralsWithIdentifiers: vasitəsilə əvvəlcədən tanınan cihaza qoşulduqda. Obyekt alındıqdan sonra developer CBCentralManager-da connectPeripheral: çağırır, bundan sonra CBPeripheral GATT əməliyyatları üçün əlçatan olur.
CBPeripheral həyat dövrü altı vəziyyəti əhatə edir: disconnected (ilkin), connecting (connect çağırışından sonra), connected (didConnectPeripheral-dən sonra), discovering (discoverServices çağırışı zamanı), discovered (servislər alındıqdan sonra) və disconnecting (cancelPeripheralConnection-dan sonra). Hər vəziyyət CBPeripheralDelegate delegatı vasitəsilə izlənilir — iOS-da hər BLE tətbiqi üçün məcburi protokol.
CBPeripheral üç səviyyədən ibarət iyerarxik GATT strukturu saxlayır. Kök səviyyə — CBService massivi (servislər), hər servis CBCharacteristic massivi (xarakteristikalar), hər xarakteristika CBDescriptor massivi (deskriptorlar) ehtiva edir. Bu model Bluetooth GATT spesifikasiyasına tam uyğundur: servis — cihazın funksiyası (məsələn, "Heart Rate Service"), xarakteristika — konkret dəyər (nəbz 72 bpm), deskriptor — xarakteristikanın metadatası (ölçü vahidləri, bildiriş konfiqurasiyası).
| Səviyyə | Core Bluetooth sinfi | Təsvir |
|---|---|---|
| Servis | CBService | Əlaqəli xarakteristikaların məntiqi qrupu, UUID (16-bit, 32-bit və ya 128-bit) ilə identifikasiya olunur |
| Xarakteristika | CBCharacteristic | Konkret məlumat dəyəri, oxu, yazı, bildiriş dəstəkləyir |
| Deskriptor | CBDescriptor | Xarakteristikanın metadatası: CCCD kliet konfiqurasiyası, User Description, Presentation Format |
Standart BLE-servislər Bluetooth SIG-də qeydiyyatdan keçib: Heart Rate Service (UUID 180D), Battery Service (180F), Device Information (180A), Blood Pressure (1810). Xüsusi servislər üçün 128-bit UUID istifadə olunur (məsələn, E20A39F4-73F5-4BC4-A12F-17D1AD07A961). iOS standart UUID-ləri avtomatik tanıyır və insan tərəfindən oxuna bilən adlar göstərir; xüsusi UUID-lər hex formatında göstərilir.
CBPeripheral qoşulduqdan sonra onun iyerarxiyası boşdur — servislər və xarakteristikalar yüklənməyib. Developer servisləri əldə etmək üçün discoverServices: çağırmalı, sonra hər servis üçün discoverCharacteristics:forService: çağırmalıdır. Servis daxil edilmiş servislər (includedServices) ehtiva edirsə, əlavə olaraq discoverIncludedServices:forService: çağırılır. Yalnız discovery iyerarxiyası tamamlandıqdan sonra CBPeripheral doldurulur və oxu/yazı üçün əlçatan olur.
Discovery (aşkaretmə) CBPeripheral GATT strukturunun — hər hansı oxu və ya yazı əməliyyatından əvvəl məcburi addımdır. discoverServices: metodu cihazın bütün servislərinin asinxron axtarışını başladır. Nil ötürülərsə, bütün servislər aşkar edilir; CBUUID massivi ötürülərsə — yalnız göstərilən UUID-li servislər (vaxt optimizasiyası). Nəticə peripheral:didDiscoverServices: delegatına gəlir — CBPeripheral obyekti services xassəsini CBService massivi ilə doldurur.
Servislər alındıqdan sonra hər CBService üçün discoverCharacteristics:forService: çağırılmalıdır. Eynilə, nil — bütün xarakteristikalar, CBUUID massivi — yalnız göstərilənlər. Nəticə: peripheral:didDiscoverCharacteristicsForService:error:. Bu mərhələdə CBCharacteristic icazə verilən əməliyyatları müəyyən edən xüsusiyyətlər (properties: .read, .write, .notify, .indicate) alır.
import CoreBluetooth
extension BLEViewController: CBPeripheralDelegate {
// 1. Servis discovery-si
func peripheral(_ peripheral: CBPeripheral,
didDiscoverServices error: Error?) {
guard let services = peripheral.services else { return }
for service in services {
// Hər servis üçün xarakteristikaların tələbi
peripheral.discoverCharacteristics(nil, for: service)
}
}
// 2. Xarakteristika discovery-si
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. Dəyərin oxunması
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)")
}
}
Nümunədə CBPeripheralDelegate-in üç məcburi aşkaretmə metodu tətbiq edilib. didDiscoverServices bütün tapılan servisləri dövr edir və xarakteristikaları tələb edir. didDiscoverCharacteristicsForService hər xarakteristikanın xüsusiyyətlərini yoxlayır: .read üçün readValue çağırır, .notify üçün — setNotifyValue(true). didUpdateValueForCharacteristic metodu cari dəyəri Data formatında alır.
Dəyərlərin oxunması CBCharacteristic readValueForCharacteristic: metodu ilə həyata keçirilir. Nəticə asinxron olaraq peripheral:didUpdateValueForCharacteristic:error:-da gəlir. Vacib: cihazda keşlənmiş dəyər ola bilər (characteristic.value discovery-dən dərhal sonra əlçatandır), lakin cari dəyəri əldə etmək üçün readValue çağırışı məcburidir. iOS enerji səmərəliliyi üçün dəyərləri keşləyə bilər — readValue keşi yeniləyir.
Dəyərlərin yazılması writeValue:forCharacteristic:type: metodu ilə həyata keçirilir. type parametri yazı tipini müəyyən edir: .withResponse (CBCharacteristicWriteWithResponse) — cihaz didWriteValueForCharacteristic vasitəsilə yazını təsdiqləyir; .withoutResponse (CBCharacteristicWriteWithoutResponse) — təsdiqsiz yazı, maksimal sürət, lakin çatdırılma zəmanətsiz. BLE spesifikasiyası MTU-nu (Maximum Transmission Unit) məhdudlaşdırır: BLE 4.0 üçün 23 baytadək, BLE 5.0+ üçün 251 baytadək. MTU-dan böyük məlumatlar üçün tətbiq səviyyəsində fraqmentasiya tələb olunur.
// CBPeripheral xarakteristika oxu və yazısı
class BLEService {
private let peripheral: CBPeripheral
private let serviceUUID = CBUUID(string: "180D")
private let charUUID = CBUUID(string: "2A37")
init(peripheral: CBPeripheral) {
self.peripheral = peripheral
}
// Təsdiqlə oxu
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)
}
// Təsdiqlə yazı (withResponse)
func writeWithResponse(data: Data) {
guard let characteristic = findCharacteristic() else { return }
peripheral.writeValue(data, for: characteristic,
type: .withResponse)
}
// Təsdiqsiz yazı (withoutResponse)
// Maksimal ötürmə, çatdırılma zəmanətsiz
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 })
}
}
withResponse və ya withoutResponse yazı tipinin seçimi etibarlılıq tələblərindən asılıdır. Komandalar üçün (işığı yandır, qıfılı aç) withResponse istifadə edin — çatdırılma zəmanəti kritikdir. Axın məlumatları üçün (nəbz, temperatur) withoutResponse istifadə edin — bir paketin itirilməsi əhəmiyyətsizdir. BLE cihazı yalnız bir yazı tipini dəstəkləyə bilər — characteristic.properties.contains(.write) və .writeWithoutResponse xassəsini yoxlayın.
Bildirişlər (notifications) — periferik cihazın xarakteristika dəyərini mərkəzi cihaza asinxron göndərdiyi BLE mexanizmidir, mərkəzi tərəfdən daimi polling tələb olunmur. CBPeripheral setNotifyValue:forCharacteristic: metodu vasitəsilə abunəliyi aktivləşdirir. Abunəlik aktivləşdirildikdən sonra iOS avtomatik olaraq periferiyada CCCD (Client Characteristic Configuration Descriptor) yazır və cihaz hər dəyər dəyişikliyində yeniləmələr göndərməyə başlayır.
İndikasiyalardan (indicate) fərqli olaraq, bildirişlər mərkəzi tərəfdən təsdiq tələb etmir — paket göndərilir və unudulur. Bu maksimal ötürmə qabiliyyəti verir, lakin paket itkisi mümkündür. İndikasiyalar protokol səviyyəsində (L2CAP) təsdiq tələb edir — daha etibarlı, lakin yavaşdır. CBCharacteristic properties xassəsi vasitəsilə hansı rejimi dəstəklədiyini dəqiq göstərir: .notify, .indicate və ya hər ikisi.
CBPeripheral söndürüldükdə (disconnect, zonalı tərk etdikdə) bütün aktiv abunəliklər avtomatik sıfırlanır. Təkrar qoşulduqda hər xarakteristika üçün yenidən setNotifyValue:true çağırılmalıdır. iOS tətbiq foreground-dan çıxdıqda da abunəlikləri itirir (background mode aktiv deyilsə) — fon işi üçün Info.plist-də "Uses Bluetooth LE accessories" capability-i aktivləşdirilməlidir.
// CBPeripheral bildiriş abunəliyinin idarə edilməsi
class NotificationManager: NSObject {
private var peripheral: CBPeripheral?
private var subscribedCharacteristics: Set<CBUUID> = []
// Bütün .notify xarakteristikaları üçün bildirişlərə abunə ol
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)
}
}
}
}
// Bütün bildirişlərdən abunəliyi ləğv et
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()
}
// Bildiriş handleri
func peripheral(_ peripheral: CBPeripheral,
didUpdateNotificationStateFor characteristic: CBCharacteristic,
error: Error?) {
if characteristic.isNotifying {
print("Subscription active: \(characteristic.uuid)")
} else {
print("Subscription inactive: \(characteristic.uuid)")
}
}
}
NotificationManager abunəlik meneceri CBPeripheral bildirişləri ilə düzgün işi nümayiş etdirir. subscribeToAllNotifications bütün servisləri və xarakteristikaları dövr edir, .notify və .indicate aktivləşdirir. subscribedCharacteristics düzgün abunəlikdən çıxma üçün aktiv abunəlikləri izləyir. didUpdateNotificationStateForCharacteristic characteristic.isNotifying xassəsi vasitəsilə abunəlik vəziyyətinin uğurlu dəyişməsini təsdiqləyir.
CBPeripheral ilə tam iş dövrü daxildir: CBCentralManager-dən obyektin alınması, qoşulma, discovery, oxu/yazı, bildirişlərə abunəlik və söndürmə. Aşağıdakı nümunədə Swift-də müasir async/await API (iOS 15+) istifadə edərək BLE-periferiyanın tam həyat dövrünü idarə edən BLEConnection sinfi tətbiq edilmişdir.
import CoreBluetooth
// async/await ilə tam CBPeripheral idarəetmə nümunəsi
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. Periferik cihaza qoşul
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. Discovery
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 cihaz vəziyyətini idarə et
}
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
}
BLEConnection sinfi CheckedContinuation vasitəsilə Swift Concurrency (async/await) istifadə edir — Core Bluetooth delegat API-ləri ilə iş üçün müasir nümunədir. connect(to:) didConnectPeripheral vasitəsilə qoşulma təsdiqini gözləyir, discoverServices() — didDiscoverServices vasitəsilə. Bu yanaşma iç-içə delegatlardan xilas edir və BLE kodunu xətti və oxunaqlı edir. BLEError vasitəsilə xəta idarəetməsi BLE bağlantısının bütün tipik uğursuzluq ssenarilərini əhatə edir.
Tez-tez verilən suallar
CBPeripheral əvvəllər qoşulmuş cihaz üçün CBCentralManager-da retrievePeripheralsWithIdentifiers: vasitəsilə əldə edilə bilər. Əvvəlcədən saxlanmış cihazların UUID (NSUUID) massivini ötürün — framework sistem BLE-bondinq bazasında olan cihazlar üçün CBPeripheral massivi qaytaracaq. Bu yalnız iPhone-un əvvəllər qoşulduğu cihazlar üçün işləyir. Yeni cihaz üçün skan etmə məcburendir.
Əsas səbəblər: cihaz zonaladan kənardadır (RSSI həddən aşağı), BLE radiosu söndürülmüşdür (CBCentralManager.state != .poweredOn), CBPeripheralDelegate təyin edilməmişdir (peripheral.delegate = self) və ya discoverServices qoşulmadan əvvəl çağırılmışdır. centralManager.state statusunu yoxlayın, delegatın connect çağırışından əvvəl təyin edildiyinə əmin olun və 5–10 saniyə timeout ilə retry istifadə edin.
Səbəb — yalnız .writeWithoutResponse dəstəkləyən xarakteristikada .withResponse istifadəsi və ya əksi. characteristic.properties-i çağırışdan əvvəl yoxlayın. MTU problemi də ola bilər: məlumat > 20 bayt (BLE 4.0 MTU) olduqda negotiateMTU və ya fraqmentasiya vasitəsilə MTU uzlaşması tələb olunur. Maksimal paket ölçüsünü təyin etmək üçün peripheral.maximumWriteValueLength(for: .withResponse) istifadə edin.
Zonaladan kənar CBPeripheral dərhal sönmür — iOS onu timeout vasitəsilə (adətən 20–30 saniyə) .disconnected vəziyyətinə keçirir. İzləmə üçün CBPeripheral-da readRSSI istifadə edin — əlçatmaz olduqda CBError.connectionTimeout kodu ilə xəta qaytaracaq. Həmçinin bağlantı qırılmasının vaxtında aşkarlanması üçün centralManager:didDisconnectPeripheral:error:-i izləyin.
Core Bluetooth thread-təhlükəsiz deyil — bütün CBPeripheral çağırışları bir növbədən icra edilməlidir (adətən main queue və ya CBCentralManager-in inisializasiyasında göstərilən ardıcıl serial queue). Müxtəlif thread-lərdən eyni vaxtda çağırışlar race condition və tətbiqin çökməsinə səbəb olur. Bütün BLE əməliyyatları üçün DispatchQueue(label: "com.app.ble") və UI yeniləməsi üçün DispatchQueue.main.async istifadə edin.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun