Core Bluetooth هو إطار عمل Apple للتفاعل مع Bluetooth Low Energy على iOS و iPadOS و macOS. يوفر الإطار مجموعة كاملة من واجهات برمجة التطبيقات للعمل في كلا دوري BLE: الجهاز المركزي (CBCentralManager) للمسح والاتصال بالأجهزة الطرفية، والجهاز الطرفي (CBPeripheralManager) لمحاكاة خادم BLE. يقوم Core Bluetooth بتجريد مكدس بروتوكول BLE من الراديو المادي إلى ملف GATT على مستوى التطبيق. وفقًا لـ Apple Developer، 2026، فإن Core Bluetooth هو واجهة برمجة التطبيقات الرسمية الوحيدة من Apple لتطوير BLE، ويدعم BLE 4.0–5.4 مع الإعلان الموسع و 2M PHY و LE Audio.
أهم النقاط
Core Bluetooth يقسم مكدس BLE إلى دورين منطقيين محددين بواسطة مواصفات Bluetooth SIG. يتم تمثيل دور الجهاز المركزي (Central) بفئة CBCentralManager — حيث يبدأ المسح، ويؤسس الاتصالات، ويدير قائمة الأجهزة الطرفية CBPeripheral المتصلة. يتم تمثيل دور الجهاز الطرفي (Peripheral) بفئة CBPeripheralManager — حيث ينشر الخدمات والخصائص، ويستجيب لطلبات الجهاز المركزي، ويرسل الإشعارات. يمكن لجلسة iOS واحدة أن تعمل في كلا الدورين في وقت واحد على راديوات BLE مختلفة، لكن التطبيق النموذجي يستخدم دورًا واحدًا.
تتضمن بنية Core Bluetooth خمسة تجريدات رئيسية. CBCentralManager يدير حالة محول Bluetooth للجهاز: poweredOn (جاهز للعمل)، poweredOff (Bluetooth معطل)، unauthorized (بدون إذن)، unsupported (BLE غير متاح). CBPeripheral يمثل جهاز BLE عن بعد مع UUID واسمه و RSSI والتسلسل الهرمي GATT. CBService — مجموعة منطقية من الخصائص. CBCharacteristic — نقطة بيانات للقراءة/الكتابة/الإشعارات. CBPeripheralManager ينشئ خادم GATT محليًا لمحاكاة جهاز طرفي.
| الفئة | الدور | الطرق الرئيسية |
|---|---|---|
| CBCentralManager | الجهاز المركزي | scanForPeripherals, connect, cancelPeripheralConnection, retrievePeripherals |
| CBPeripheral | الجهاز الطرفي عن بعد | discoverServices, discoverCharacteristics, readValue, writeValue, setNotifyValue |
| CBPeripheralManager | الجهاز الطرفي المحلي | addService, removeService, startAdvertising, respondToRequest, updateValue |
| CBCentral | المركزي عن بعد | maximumUpdateValueLength, identifier, ancsAuthorized |
حالات CBCentralManager تتحكم في جميع عمليات BLE. عند بدء التطبيق، يتم استدعاء centralManagerDidUpdateState مع حالة Bluetooth الحالية. إذا لم تكن الحالة .poweredOn، يتجاهل النظام أي استدعاءات BLE. يجب على المطور التحقق من الحالة قبل كل مسح واتصال. يحدث الانتقال من .poweredOff إلى .poweredOn عند تشغيل Bluetooth في إعدادات iOS — يتلقى المفوض استدعاءً متكررًا، ويمكن للتطبيق استئناف المسح.
CBCentralManager هو نقطة الدخول لجميع عمليات BLE من جانب الجهاز المركزي. تقبل التهيئة مفوضًا (CBCentralManagerDelegate) و DispatchQueue — توصي Apple باستخدام قائمة الانتظار الرئيسية للبساطة أو قائمة انتظار تسلسلية للأداء. بعد التهيئة، يتحقق الإطار تلقائيًا من حالة Bluetooth ويستدعي centralManagerDidUpdateState: — أول مفوض إلزامي يجب معالجته.
يبدأ المسح بطريقة scanForPeripheralsWithServices:options:. المعامل الأول هو مصفوفة من CBUUID للخدمات للتصفية: إذا كانت معرفات UUID للخدمات المطلوبة معروفة، فإن تمريرها يقلل من استهلاك الطاقة ووقت البحث. إذا كان nil، يتم اكتشاف جميع أجهزة BLE في النطاق. تتضمن الخيارات .allowDuplicatesKey (الاكتشافات المتكررة لنفس الجهاز) و .solicitedServiceUUIDsKey (للخدمات المنشورة على المركزي).
import CoreBluetooth
class BLECentral: NSObject {
private var centralManager: CBCentralManager!
private var discoveredPeripherals: [CBPeripheral] = []
override init() {
super.init()
centralManager = CBCentralManager(delegate: self, queue: .main)
}
// بدء مسح BLE
func startScan() {
guard centralManager.state == .poweredOn else {
print("Bluetooth غير متاح")
return
}
// مسح جميع الأجهزة (nil = بدون فلتر)
centralManager.scanForPeripherals(withServices: nil,
options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
}
// إيقاف المسح
func stopScan() {
centralManager.stopScan()
}
// الاتصال بالجهاز المحدد
func connect(to peripheral: CBPeripheral) {
centralManager.connect(peripheral, options: nil)
}
}
// MARK: - CBCentralManagerDelegate
extension BLECentral: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
startScan()
}
}
func centralManager(_ central: CBCentralManager,
didDiscover peripheral: CBPeripheral,
advertisementData: [String : Any],
rssi: NSNumber) {
if !discoveredPeripherals.contains(where: { $0.identifier == peripheral.identifier }) {
discoveredPeripherals.append(peripheral)
print("Found devices: \(peripheral.name ?? "Unknown"), RSSI: \(rssi)")
}
}
func centralManager(_ central: CBCentralManager,
didConnect peripheral: CBPeripheral) {
print("Connected: \(peripheral.identifier)")
peripheral.delegate = self
peripheral.discoverServices(nil)
}
func centralManager(_ central: CBCentralManager,
didDisconnectPeripheral peripheral: CBPeripheral,
error: Error?) {
print("Disconnected: \(peripheral.identifier)")
}
}
توضح فئة BLECentral دورة كاملة لمسح أجهزة BLE والاتصال بها. يبدأ centralManagerDidUpdateState المسح عند تمكين Bluetooth. يقوم didDiscoverPeripheral بتجميع الأجهزة التي تم العثور عليها في مصفوفة discoveredPeripherals مع إزالة التكرار حسب identifier. بعد الاتصال (didConnect)، يبدأ اكتشاف الخدمات فورًا — هذه خطوة إلزامية قبل أي عمليات GATT.
CBPeripheralManager هي الفئة لمحاكاة جهاز BLE طرفي على iOS. يمكن للتطبيق في الدور الطرفي نشر خدماته وخصائصه، وقبول طلبات القراءة/الكتابة الواردة من جهاز مركزي، وإرسال الإشعارات. يُستخدم CBPeripheralManager لملحقات BLE التي يحاكيها iPhone: أجهزة التحكم عن بعد، لوحات المفاتيح، أجهزة التتبع، بوابات IoT.
تبدأ دورة حياة CBPeripheralManager بالتهيئة والمفوض CBPeripheralManagerDelegate. بعد تأكيد poweredOn عبر peripheralManagerDidUpdateState:، يتم نشر الخدمات (addService:) وبدء الإعلان (startAdvertising:). تتضمن بيانات الإعلان CBAdvertisementData الاسم المحلي (CBAdvertisementDataLocalNameKey)، ومعرفات UUID للخدمات (CBAdvertisementDataServiceUUIDsKey)، ومستوى طاقة الإرسال (CBAdvertisementDataTxPowerLevelKey). الحد الأقصى لحجم حزمة الإعلان هو 31 بايت لـ BLE 4.0، و 251 بايت للإعلان الموسع BLE 5.0+.
// جهاز BLE طرفي على iOS عبر CBPeripheralManager
class BLEPeripheral: NSObject {
private var peripheralManager: CBPeripheralManager!
let serviceUUID = CBUUID(string: "1234")
let characteristicUUID = CBUUID(string: "5678")
override init() {
super.init()
peripheralManager = CBPeripheralManager(delegate: self, queue: .main)
}
// نشر الخدمة مع الخاصية
func setupService() {
let characteristic = CBMutableCharacteristic(
type: characteristicUUID,
properties: [.read, .write, .notify],
value: nil,
permissions: [.readable, .writeable]
)
let service = CBMutableService(type: serviceUUID, primary: true)
service.characteristics = [characteristic]
peripheralManager.add(service)
}
// بدء الإعلان
func startAdvertising() {
let advertisementData: [String: Any] = [
CBAdvertisementDataLocalNameKey: "My BLE Device",
CBAdvertisementDataServiceUUIDsKey: [serviceUUID]
]
peripheralManager.startAdvertising(advertisementData)
}
}
// MARK: - CBPeripheralManagerDelegate
extension BLEPeripheral: CBPeripheralManagerDelegate {
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
if peripheral.state == .poweredOn {
setupService()
}
}
func peripheralManager(_ peripheral: CBPeripheralManager,
didAdd service: CBService,
error: Error?) {
if error == nil {
startAdvertising()
}
}
// معالجة طلب القراءة
func peripheralManager(_ peripheral: CBPeripheralManager,
didReceiveRead request: CBATTRequest) {
let data = "CurrentValue".data(using: .utf8)!
request.value = data
peripheralManager.respond(to: request, withResult: .success)
}
// معالجة طلب الكتابة
func peripheralManager(_ peripheral: CBPeripheralManager,
didReceiveWrite requests: [CBATTRequest]) {
for request in requests {
if let value = request.value {
print("Write: \(value)")
}
}
peripheralManager.respond(to: requests.first!, withResult: .success)
}
}
تنشئ فئة BLEPeripheral خادم BLE بخاصية واحدة تدعم القراءة والكتابة والإشعارات. بعد التهيئة، ينشر peripheralManagerDidUpdateState الخدمة عبر addService:، ثم يبدأ الإعلان عبر startAdvertising:. تتعامل معالجات didReceiveRead و didReceiveWrite مع طلبات GATT الواردة من الجهاز المركزي. تُستخدم طريقة updateValue:forCharacteristic:onSubscribedCentrals: لإرسال الإشعارات.
عمليات GATT (Generic Attribute Profile) هي أساس تبادل البيانات في Core Bluetooth. بعد اكتشاف الخدمات والخصائص، يمكن للجهاز المركزي تنفيذ ثلاثة أنواع من العمليات: قراءة قيمة الخاصية، وكتابة قيمة، والاشتراك في الإشعارات/التنبيهات. كل عملية غير متزامنة وتعيد النتيجة عبر مفوض CBPeripheralDelegate المقابل.
القراءة: تتم عن طريق استدعاء readValueForCharacteristic:. تصل القيمة في peripheral:didUpdateValueForCharacteristic:error:. مهم: القراءة تعيد القيمة الحالية من الجهاز، وليس قيمة مخبأة. إذا كان الجهاز لا يدعم القراءة (خاصية .read)، سيعيد الاستدعاء خطأ. للقيم الكبيرة (أكبر من MTU)، يقوم BLE تلقائيًا بتجزئة وإعادة تجميع البيانات على مستوى GATT.
الكتابة: تتم عن طريق استدعاء writeValue:forCharacteristic:type:. يدعم BLE نموذجي كتابة: withResponse (موثوق، مع تأكيد) و withoutResponse (سريع، بدون تأكيد). تحدد خاصية CBCharacteristic.properties أنواع الكتابة المتاحة. الحد الأقصى لحجم حزمة كتابة واحدة محدود بـ MTU: 23 بايت لـ BLE 4.0 (20 بايت من البيانات + 3 بايت من الرأس)، حتى 247 بايت لـ BLE 5.0 مع MTU ممتد (MTU 251).
الإشعارات: يتم تنشيطها عن طريق استدعاء setNotifyValue:true forCharacteristic:. بعد الاشتراك، يرسل الجهاز الطرفي التحديثات تلقائيًا عبر peripheral:didUpdateValueForCharacteristic: كلما تغيرت قيمة الخاصية. لتعطيل الإشعارات، يتم استدعاء setNotifyValue:false forCharacteristic:. يقوم Core Bluetooth بإدارة واصف CCCD على الجهاز الطرفي تلقائيًا.
| العملية | الطريقة | المفوض | نوع النقل |
|---|---|---|---|
| قراءة | readValueForCharacteristic: | didUpdateValueForCharacteristic | استقصاء (طلب-استجابة) |
| كتابة withResponse | writeValue:forCharacteristic:type:withResponse | didWriteValueForCharacteristic | مع تأكيد |
| كتابة withoutResponse | writeValue:forCharacteristic:type:withoutResponse | بدون مفوض | بدون تأكيد |
| إشعار | setNotifyValue:true forCharacteristic: | didUpdateNotificationStateForCharacteristic + didUpdateValueForCharacteristic | دفع من الجهاز الطرفي |
وضع الخلفية في Core Bluetooth يسمح لتطبيقات BLE بمواصلة المسح والحفاظ على الاتصالات وتلقي الإشعارات أثناء وجودها في الخلفية. لتفعيله، يجب تمكين إمكانية «Uses Bluetooth LE accessories» في Xcode (Info.plist → Required background modes → App communicates using Core Bluetooth) وإضافة مفتاح «bluetooth-central» إلى UIBackgroundModes. للدور الطرفي — «bluetooth-peripheral».
استعادة الحالة (State Restoration) هي آلية في Core Bluetooth لاستعادة حالة اتصالات BLE بعد إعادة تشغيل التطبيق بواسطة iOS. عندما يكون وضع الخلفية نشطًا ويتم تحديد restoreIdentifier في تهيئة CBCentralManager أو CBPeripheralManager، يحفظ iOS حالة مكدس BLE عند إنهاء التطبيق ويستعيدها في الإطلاق التالي. يتلقى المفوض centralManager:willRestoreState: قاموسًا مع أجهزة CBPeripheral المحفوظة والاتصالات المعلقة.
// تهيئة Core Bluetooth مع استعادة الحالة
class BLECentralWithRestoration: NSObject {
let restoreIdentifier = "com.app.blecentral"
private var centralManager: CBCentralManager!
override init() {
super.init()
let options: [String: Any] = [
CBCentralManagerOptionRestoreIdentifierKey: restoreIdentifier,
CBCentralManagerOptionShowPowerAlertKey: true
]
centralManager = CBCentralManager(delegate: self,
queue: nil,
options: options)
}
}
extension BLECentralWithRestoration: CBCentralManagerDelegate {
// استعادة الحالة بعد إعادة التشغيل
func centralManager(_ central: CBCentralManager,
willRestoreState dict: [String : Any]) {
if let peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey]
as? [CBPeripheral] {
for peripheral in peripherals {
peripheral.delegate = self
// استعادة اكتشاف GATT
peripheral.discoverServices(nil)
}
}
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
print("Bluetooth جاهز بعد الاستعادة")
}
}
}
في تكوين BLECentralWithRestoration، مفتاح CBCentralManagerOptionRestoreIdentifierKey يفعل حفظ الحالة. إذا تم إنهاء التطبيق بواسطة iOS (مثلًا بسبب ضغط الذاكرة)، في الإطلاق التالي يتلقى centralManager:willRestoreState: قائمة بأجهزة CBPeripheral المتصلة سابقًا. يستعيد التطبيق المفوضيات ويقوم بإعادة اكتشاف الخدمات — لا يلاحظ المستخدم انقطاع الاتصال. بدون استعادة الحالة، تُفقد جميع جلسات BLE عند إنهاء التطبيق.
مثال كامل لتطبيق BLE في Swift يجمع بين كل من الأجهزة المركزية والطرفية في مشروع واحد. يمكن للتطبيق العمل في وضعين: اكتشاف الأجهزة BLE والاتصال بها (مركزي) أو محاكاة ملحق BLE (طرفي). فيما يلي بنية مع مدير BLE مشترك يختار الدور عند بدء التشغيل.
// مدير BLE عالمي للمركزي والطرفي
class BLEManager {
enum Role {
case central
case peripheral
}
private let role: Role
private var centralManager: CBCentralManager?
private var peripheralManager: CBPeripheralManager?
let advertisedServiceUUID = CBUUID(string: "A001")
init(role: Role) {
self.role = role
switch role {
case .central:
centralManager = CBCentralManager(delegate: nil, queue: .main)
case .peripheral:
peripheralManager = CBPeripheralManager(delegate: nil, queue: .main)
}
}
// الجهاز المركزي: مسح
func scanForDevices() {
centralManager?.scanForPeripherals(withServices: nil, options: nil)
}
// الجهاز الطرفي: إعلان
func advertiseService() {
let data: [String: Any] = [
CBAdvertisementDataServiceUUIDsKey: [advertisedServiceUUID]
]
peripheralManager?.startAdvertising(data)
}
}
// الاستخدام عند بدء التشغيل
let isCentral = UserDefaults.standard.bool(forKey: "isCentral")
let manager = BLEManager(role: isCentral ? .central : .peripheral)
if isCentral {
manager.scanForDevices()
} else {
manager.advertiseService()
}
يختار BLEManager الدور عند التهيئة وينشئ المدير المقابل (CBCentralManager أو CBPeripheralManager). يمكن تخزين علامة الدور في UserDefaults أو تمريرها عبر خادم تكوين. يسمح هذا النهج لتطبيق BLE بالتكيف مع حالة الاستخدام: في نقطة البيع، يعمل iPhone كمركزي لمسح أجهزة الدفع؛ على بوابة IoT — كطرفي لجمع البيانات من أجهزة الاستشعار.
الأسئلة الشائعة
Core Bluetooth هو إطار عمل Apple لتطوير BLE على iOS و iPadOS و macOS. يوفر واجهات برمجة تطبيقات لكل من الأجهزة المركزية (CBCentralManager) والطرفية (CBPeripheralManager). يدعم BLE 4.0–5.4 والإعلان الموسع و 2M PHY و LE Audio. Core Bluetooth هو واجهة برمجة التطبيقات الرسمية الوحيدة من Apple لاتصال BLE، المطلوبة لجميع تطبيقات iOS التي تعمل مع Bluetooth Low Energy.
CBCentralManager هي فئة للعمل في دور الجهاز المركزي: تمسح الأجهزة الطرفية BLE وتؤسس الاتصالات وتقرأ وتكتب الخصائص. CBPeripheralManager هي فئة للعمل في الدور الطرفي: تنشر الخدمات وتستجيب لطلبات القراءة/الكتابة وترسل الإشعارات. يمكن لجهاز iPhone واحد العمل في كلا الدورين في وقت واحد من خلال مثيلات مدير مختلفة.
للعمل في الخلفية مع BLE، قم بتمكين إمكانية «Uses Bluetooth LE accessories» في Xcode وأضف مفتاح «bluetooth-central» إلى UIBackgroundModes. للدور الطرفي — «bluetooth-peripheral». حدد restoreIdentifier عند تهيئة المدير لاستعادة الحالة. بدون هذه الإعدادات، لن يتلقى التطبيق في الخلفية أحداث BLE وسيفقد الاتصالات.
الأسباب الشائعة: CBCentralManager.state != .poweredOn (Bluetooth معطل أو غير مصرح به)، لم يتم تعيين المفوض، الجهاز خارج النطاق أو لا يرسل حزم إعلان. تحقق من الإذن NSBluetoothAlwaysUsageDescription في Info.plist، وحالة Bluetooth في centralManagerDidUpdateState، وتأكد من استدعاء scanForPeripherals فقط عندما يكون .poweredOn.
نعم، يدعم Core Bluetooth الاتصالات المتزامنة مع أجهزة BLE متعددة. تتم إدارة كل CBPeripheral بشكل مستقل من خلال مفوض خاص به. يحد iOS من عدد اتصالات BLE المتزامنة على مستوى النظام (عادة 5–7 لـ iPhone). لسيناريوهات 1:N (مثلًا، مركز لياقة بدنية مع 10 أجهزة تتبع)، يلزم وضع قائمة انتظار وخدمة دورية للأجهزة الطرفية.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.