CBPeripheral Core Bluetooth फ्रेमवर्क का एक वर्ग है जो iOS पर एक दूरस्थ BLE डिवाइस का प्रतिनिधित्व करता है। प्रत्येक CBPeripheral ऑब्जेक्ट कनेक्टेड BLE डिवाइस के UUID, नाम, RSSI और GATT सेवा पदानुक्रम को समाहित करता है। डेवलपर विशेष रूप से CBPeripheral के माध्यम से परिधीय के साथ इंटरैक्ट करता है: सेवा खोज (discoverServices:), विशेषता पढ़ना (readValueForCharacteristic:), डेटा लेखन (writeValue:forCharacteristic:type:) और सूचना सदस्यता (setNotifyValue:forCharacteristic:)। Apple Developer, 2026 के अनुसार, CBPeripheral सभी BLE परिधीय संचालन के लिए केंद्रीय ऑब्जेक्ट है, जो डिवाइस खोज या कनेक्शन पर CBCentralManager द्वारा वापस किया जाता है।
मुख्य बिंदु
CBPeripheral एक ऑब्जेक्ट है जो iOS एप्लिकेशन में दूरस्थ BLE डिवाइस का प्रतिनिधित्व करता है। CBCentralManager के विपरीत, जो iPhone के स्थानीय Bluetooth एडेप्टर का प्रबंधन करता है, CBPeripheral एक बाहरी परिधीय डिवाइस का मॉडल बनाता है: सेंसर, फिटनेस ट्रैकर, बीकन या चिकित्सा उपकरण। प्रत्येक CBPeripheral इंस्टेंस में एक अद्वितीय पहचानकर्ता (UUID) होता है जो कनेक्शन सत्रों के बीच बना रहता है — Apple UUID को सिस्टम बॉन्डिंग के माध्यम से एक विशिष्ट डिवाइस से जोड़ता है।
CBPeripheral सीधे init के माध्यम से नहीं बनाया जाता है। Core Bluetooth फ्रेमवर्क दो परिदृश्यों में CBPeripheral ऑब्जेक्ट लौटाता है: जब scanForPeripheralsWithServices: के माध्यम से डिवाइस खोजा जाता है (प्रतिनिधि didDiscoverPeripheral) और जब retrievePeripheralsWithIdentifiers: के माध्यम से पहले से ज्ञात डिवाइस से कनेक्ट किया जाता है। ऑब्जेक्ट प्राप्त करने के बाद, डेवलपर CBCentralManager पर connectPeripheral: कॉल करता है, जिसके बाद CBPeripheral GATT संचालन के लिए उपलब्ध हो जाता है।
CBPeripheral जीवनचक्र में छह अवस्थाएँ शामिल हैं: डिस्कनेक्टेड (प्रारंभिक), कनेक्टिंग (connect कॉल के बाद), कनेक्टेड (didConnectPeripheral के बाद), खोज रहा (discoverServices कॉल के दौरान), खोजा गया (सेवाएँ प्राप्त करने के बाद) और डिस्कनेक्ट कर रहा (cancelPeripheralConnection के बाद)। प्रत्येक अवस्था CBPeripheralDelegate प्रोटोकॉल के माध्यम से ट्रैक की जाती है — iOS पर किसी भी BLE एप्लिकेशन के लिए अनिवार्य।
CBPeripheral तीन स्तरों से युक्त एक पदानुक्रमित GATT संरचना संग्रहीत करता है। मूल स्तर CBService (सेवाएँ) की एक सरणी है, प्रत्येक सेवा में CBCharacteristic (विशेषताएँ) की एक सरणी होती है, प्रत्येक विशेषता में CBDescriptor (वर्णनकर्ता) की एक सरणी होती है। यह मॉडल Bluetooth GATT विनिर्देश के अनुरूप है: सेवा एक डिवाइस फ़ंक्शन है (जैसे, “हृदय गति सेवा”), विशेषता एक विशिष्ट मान है (नाड़ी 72 bpm), वर्णनकर्ता विशेषता मेटाडेटा है (माप इकाइयाँ, सूचना कॉन्फ़िगरेशन)।
| स्तर | Core Bluetooth वर्ग | विवरण |
|---|---|---|
| सेवा | CBService | संबंधित विशेषताओं का तार्किक समूह, UUID (16-बिट, 32-बिट या 128-बिट) द्वारा पहचाना जाता है |
| विशेषता | CBCharacteristic | विशिष्ट डेटा मान, पढ़ने, लिखने और सूचनाओं का समर्थन करता है |
| वर्णनकर्ता | CBDescriptor | विशेषता मेटाडेटा: क्लाइंट कॉन्फ़िगरेशन CCCD, उपयोगकर्ता विवरण, प्रस्तुति प्रारूप |
मानक BLE सेवाएँ Bluetooth SIG द्वारा पंजीकृत हैं: Heart Rate Service (UUID 180D), Battery Service (180F), Device Information (180A), Blood Pressure (1810)। कस्टम सेवाओं के लिए 128-बिट UUID का उपयोग किया जाता है (जैसे, E20A39F4-73F5-4BC4-A12F-17D1AD07A961)। iOS स्वचालित रूप से मानक UUID को पहचानता है और मानव-पठनीय नाम प्रदर्शित करता है; कस्टम UUID हेक्स प्रारूप में दिखाई देते हैं।
कनेक्शन के बाद, CBPeripheral का पदानुक्रम खाली होता है — सेवाएँ और विशेषताएँ लोड नहीं होती हैं। डेवलपर को सेवाएँ प्राप्त करने के लिए discoverServices: कॉल करना होगा और फिर प्रत्येक सेवा के लिए discoverCharacteristics:forService: कॉल करना होगा। यदि सेवा में शामिल सेवाएँ हैं, तो अतिरिक्त रूप से discoverIncludedServices:forService: कॉल किया जाता है। पदानुक्रम खोज पूरी होने के बाद ही CBPeripheral भरा जाता है और पढ़ने और लिखने के लिए उपलब्ध होता है।
खोज CBPeripheral की GATT संरचना की किसी भी पढ़ने या लिखने के संचालन से पहले एक अनिवार्य कदम है। विधि discoverServices: सभी डिवाइस सेवाओं की एक अतुल्यकालिक खोज शुरू करती है। यदि nil पास किया जाता है, तो सभी सेवाएँ खोजी जाती हैं; यदि CBUUID की एक सरणी पास की जाती है — केवल निर्दिष्ट UUID वाली सेवाएँ (समय अनुकूलन)। परिणाम प्रतिनिधि peripheral:didDiscoverServices: में आता है — CBPeripheral ऑब्जेक्ट अपनी services संपत्ति को CBService की सरणी से भरता है।
सेवाएँ प्राप्त करने के बाद, प्रत्येक CBService के लिए discoverCharacteristics:forService: कॉल करना आवश्यक है। इसी तरह, nil — सभी विशेषताएँ, CBUUID की सरणी — केवल निर्दिष्ट। परिणाम: peripheral:didDiscoverCharacteristicsForService:error:। इस चरण में, CBCharacteristic गुण प्राप्त करता है (properties: .read, .write, .notify, .indicate) जो अनुमत संचालन को परिभाषित करते हैं।
import CoreBluetooth
extension BLEViewController: CBPeripheralDelegate {
// 1. Service discovery
func peripheral(_ peripheral: CBPeripheral,
didDiscoverServices error: Error?) {
guard let services = peripheral.services else { return }
for service in services {
// Request characteristics for each service
peripheral.discoverCharacteristics(nil, for: service)
}
}
// 2. Characteristic discovery
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. Read value
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)")
}
}
उदाहरण में, CBPeripheralDelegate तीन अनिवार्य खोज विधियों को लागू करता है। didDiscoverServices सभी मिली सेवाओं पर पुनरावृति करता है और विशेषताओं का अनुरोध करता है। didDiscoverCharacteristicsForService प्रत्येक विशेषता के गुणों की जाँच करता है: .read के लिए readValue कॉल करता है, .notify के लिए setNotifyValue(true) कॉल करता है। didUpdateValueForCharacteristic विधि Data प्रारूप में वास्तविक मान प्राप्त करती है।
मान पढ़ना CBCharacteristic का readValueForCharacteristic: विधि का उपयोग करके किया जाता है। परिणाम अतुल्यकालिक रूप से peripheral:didUpdateValueForCharacteristic:error: में आता है। महत्वपूर्ण: डिवाइस पर एक कैश्ड मान हो सकता है (विशेषता discovery के तुरंत बाद characteristic.value उपलब्ध है), लेकिन वर्तमान डेटा प्राप्त करने के लिए readValue कॉल करना अनिवार्य है। iOS ऊर्जा दक्षता के लिए मानों को कैश कर सकता है — readValue कैश को ताज़ा करता है।
मान लिखना writeValue:forCharacteristic:type: विधि का उपयोग करके किया जाता है। पैरामीटर type लेखन प्रकार निर्धारित करता है: .withResponse (CBCharacteristicWriteWithResponse) — डिवाइस didWriteValueForCharacteristic के माध्यम से लेखन की पुष्टि करता है; .withoutResponse (CBCharacteristicWriteWithoutResponse) — बिना पुष्टि के लेखन, अधिकतम गति लेकिन वितरण की कोई गारंटी नहीं। BLE विनिर्देश MTU (अधिकतम संचरण इकाई) को सीमित करता है: BLE 4.0 के लिए 23 बाइट्स तक, BLE 5.0+ के लिए 251 बाइट्स तक। MTU से बड़े डेटा के लिए एप्लिकेशन स्तर पर विखंडन आवश्यक है।
// CBPeripheral characteristic read and write
class BLEService {
private let peripheral: CBPeripheral
private let serviceUUID = CBUUID(string: "180D")
private let charUUID = CBUUID(string: "2A37")
init(peripheral: CBPeripheral) {
self.peripheral = peripheral
}
// Read with response
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)
}
// Write with response (withResponse)
func writeWithResponse(data: Data) {
guard let characteristic = findCharacteristic() else { return }
peripheral.writeValue(data, for: characteristic,
type: .withResponse)
}
// Write without response (withoutResponse)
// Max throughput, no delivery guarantee
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 या withoutResponse का चुनाव विश्वसनीयता आवश्यकताओं पर निर्भर करता है। कमांड के लिए (लाइट चालू करें, दरवाज़ा खोलें) withResponse का उपयोग करें — वितरण की गारंटी महत्वपूर्ण है। स्ट्रीमिंग डेटा (नाड़ी, तापमान) के लिए withoutResponse का उपयोग करें — एक पैकेट का खो जाना महत्वपूर्ण नहीं है। BLE डिवाइस केवल एक लेखन प्रकार का समर्थन कर सकता है — characteristic.properties.contains(.write) और .writeWithoutResponse गुण की जाँच करें।
सूचनाएँ एक BLE तंत्र हैं जिसमें परिधीय डिवाइस केंद्रीय डिवाइस को विशेषता मान अतुल्यकालिक रूप से भेजता है, बिना केंद्रीय की ओर से निरंतर पोलिंग के। CBPeripheral setNotifyValue:forCharacteristic: विधि के माध्यम से सदस्यता सक्षम करता है। सदस्यता सक्रिय करने के बाद, iOS स्वचालित रूप से परिधीय पर CCCD (क्लाइंट विशेषता कॉन्फ़िगरेशन वर्णनकर्ता) में लिखता है, और डिवाइस मान बदलने पर अपडेट भेजना शुरू करता है।
संकेतों (indications) के विपरीत, सूचनाएँ केंद्रीय डिवाइस से पुष्टि की आवश्यकता नहीं होती — पैकेट भेजा जाता है और भुला दिया जाता है। यह अधिकतम थ्रूपुट प्रदान करता है, लेकिन पैकेट खो सकते हैं। संकेतों को प्रोटोकॉल स्तर (L2CAP) पर पुष्टि की आवश्यकता होती है — अधिक विश्वसनीय लेकिन धीमी। CBCharacteristic का properties गुण सटीक रूप से इंगित करता है कि कौन सा मोड समर्थित है: .notify, .indicate या दोनों।
जब CBPeripheral डिस्कनेक्ट होता है (डिस्कनेक्ट, सीमा से बाहर), सभी सक्रिय सदस्यताएँ स्वचालित रूप से रीसेट हो जाती हैं। पुन: कनेक्शन पर, प्रत्येक विशेषता के लिए फिर से setNotifyValue:true कॉल करना होगा। iOS एप्लिकेशन के अग्रभूमि छोड़ने पर भी सदस्यताएँ खो देता है (यदि पृष्ठभूमि मोड सक्षम नहीं है) — पृष्ठभूमि संचालन के लिए Info.plist में क्षमता “Uses Bluetooth LE accessories” सक्षम करना आवश्यक है।
// CBPeripheral notification subscription management
class NotificationManager: NSObject {
private var peripheral: CBPeripheral?
private var subscribedCharacteristics: Set<CBUUID> = []
// Subscribe to notifications for all .notify characteristics
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)
}
}
}
}
// Unsubscribe from all notifications
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()
}
// Notification handler
func peripheral(_ peripheral: CBPeripheral,
didUpdateNotificationStateFor characteristic: CBCharacteristic,
error: Error?) {
if characteristic.isNotifying {
print("Subscription active: \(characteristic.uuid)")
} else {
print("Subscription inactive: \(characteristic.uuid)")
}
}
}
NotificationManager CBPeripheral सूचनाओं के उचित प्रबंधन को प्रदर्शित करता है। subscribeToAllNotifications सभी सेवाओं और विशेषताओं पर पुनरावृति करता है, .notify और .indicate सक्रिय करता है। subscribedCharacteristics उचित सदस्यता रद्द करने के लिए सक्रिय सदस्यताओं को ट्रैक करता है। didUpdateNotificationStateForCharacteristic characteristic.isNotifying गुण के माध्यम से सफल सदस्यता स्थिति परिवर्तन की पुष्टि करता है।
पूर्ण कार्यप्रवाह CBPeripheral के साथ शामिल है: CBCentralManager से ऑब्जेक्ट प्राप्त करना, कनेक्शन, खोज, पढ़ना/लिखना, सूचना सदस्यता और डिस्कनेक्शन। नीचे दिया गया उदाहरण BLEConnection वर्ग लागू करता है जो आधुनिक async/await API (iOS 15+) का उपयोग करके Swift में पूर्ण BLE परिधीय जीवनचक्र का प्रबंधन करता है।
import CoreBluetooth
// Full CBPeripheral management example with async/await
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. Connect to peripheral
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) {
// Handle Bluetooth device state
}
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 वर्ग CheckedContinuation के माध्यम से Swift Concurrency (async/await) का उपयोग करता है — Core Bluetooth के प्रतिनिधि-आधारित API के साथ काम करने के लिए एक आधुनिक पैटर्न। connect(to:) didConnectPeripheral के माध्यम से कनेक्शन पुष्टि की प्रतीक्षा करता है, discoverServices() — didDiscoverServices के माध्यम से। यह दृष्टिकोण नेस्टेड प्रतिनिधियों को समाप्त करता है और BLE कोड को रैखिक और पठनीय बनाता है। BLEError के माध्यम से त्रुटि प्रबंधन सभी विशिष्ट BLE कनेक्शन विफलता परिदृश्यों को कवर करता है।
अक्सर पूछे जाने वाले प्रश्न
CBPeripheral पहले से कनेक्टेड डिवाइस के लिए CBCentralManager पर retrievePeripheralsWithIdentifiers: के माध्यम से प्राप्त किया जा सकता है। पहले से सहेजे गए डिवाइसों के UUID (NSUUID) की एक सरणी पास करें — फ्रेमवर्क सिस्टम BLE बॉन्डिंग डेटाबेस में डिवाइसों के लिए CBPeripheral की एक सरणी लौटाता है। यह केवल उन डिवाइसों के लिए काम करता है जिनके साथ iPhone पहले युग्मित किया गया है। नए डिवाइस के लिए, स्कैनिंग अनिवार्य है।
सामान्य कारण: डिवाइस सीमा से बाहर है (RSSI थ्रेशोल्ड से नीचे), BLE रेडियो बंद है (CBCentralManager.state != .poweredOn), CBPeripheralDelegate सेट नहीं है (peripheral.delegate = self), या कनेक्शन से पहले discoverServices कॉल किया गया था। centralManager.state जाँचें, सुनिश्चित करें कि connect कॉल से पहले प्रतिनिधि सेट है, और 5–10 सेकंड टाइमआउट के साथ पुनः प्रयास का उपयोग करें।
कारण केवल .writeWithoutResponse का समर्थन करने वाली विशेषता पर .withResponse का उपयोग करना है, या इसके विपरीत। कॉल करने से पहले characteristic.properties जाँचें। एक अन्य संभावित समस्या MTU है: यदि डेटा 20 बाइट्स (BLE 4.0 MTU) से अधिक है, तो negotiateMTU या विखंडन के माध्यम से MTU वार्ता आवश्यक है। अधिकतम पैकेट आकार निर्धारित करने के लिए peripheral.maximumWriteValueLength(for: .withResponse) का उपयोग करें।
सीमा से बाहर CBPeripheral तुरंत डिस्कनेक्ट नहीं होता — iOS इसे टाइमआउट (आमतौर पर 20–30 सेकंड) के बाद .disconnected स्थिति में स्थानांतरित करता है। निगरानी के लिए, CBPeripheral पर readRSSI का उपयोग करें — यदि अनुपलब्ध है, तो यह CBError.connectionTimeout कोड के साथ त्रुटि लौटाएगा। कनेक्शन हानि का समय पर पता लगाने के लिए centralManager:didDisconnectPeripheral:error: की भी निगरानी करें।
Core Bluetooth थ्रेड-सुरक्षित नहीं है — सभी CBPeripheral कॉल एक ही कतार से की जानी चाहिए (आमतौर पर मुख्य कतार या CBCentralManager को आरंभ करते समय निर्दिष्ट अनुक्रमिक कतार)। विभिन्न थ्रेड्स से समवर्ती कॉल रेस कंडीशन और एप्लिकेशन क्रैश का कारण बनती हैं। सभी BLE संचालन के लिए DispatchQueue(label: “com.app.ble”) और UI अपडेट के लिए DispatchQueue.main.async का उपयोग करें।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें