CBCentralManager در iOS — چیست، مدیریت BLE و Core Bluetooth

نویسنده: IT Sectr منتشر شده: 2026-07-16 زمان مطالعه: 11 دقیقه

CBCentralManager — کلاس مرکزی فریمورک Core Bluetooth در iOS است که اسکن، اتصال و تعامل با دستگاه‌های پریفرال BLE را مدیریت می‌کند. Core Bluetooth (iOS 5+، 2011) یک لایه انتزاعی سطح بالا بر روی پشته BLE در سطح GATT ارائه می‌دهد و جزئیات Link Layer و HCI را از توسعه‌دهنده پنهان می‌کند. CBCentralManager نقش Central را ایفا می‌کند: اتر را از طریق scanForPeripherals اسکن می‌کند، اتصال را از طریق connect آغاز می‌کند، سرویس‌ها را از طریق discoverServices کشف می‌کند و انتقال داده را مدیریت می‌کند. طبق Apple Developer Documentation (2024)، CBCentralManager تا 7 اتصال همزمان BLE را در دستگاه‌های دارای BLE 5.0 پشتیبانی می‌کند.

نکات کلیدی

  • CBCentralManager — کلاس iOS برای مدیریت اسکن BLE، اتصال و انتقال داده در نقش Central.
  • اسکن از طریق scanForPeripherals با فیلتر کردن بر اساس UUID سرویس‌ها برای صرفه‌جویی در انرژی راه‌اندازی می‌شود.
  • اتصال از طریق connect(peripheral:options:) با ردیابی وضعیت از طریق دلیگیت انجام می‌شود.
  • iOS تا 7 اتصال همزمان BLE را در دستگاه‌های دارای BLE 5.0 پشتیبانی می‌کند.
  • اسکن پس‌زمینه نیاز به فعال‌سازی bluetooth-central در Background Modes و استفاده از CBCentralManagerScanOptionAllowDuplicatesKey دارد.

CBCentralManager چیست؟

CBCentralManager — کلاس اصلی Core Bluetooth برای پیاده‌سازی نقش Central در معماری BLE در iOS است. این کلاس کل چرخه حیات اتصال BLE را مدیریت می‌کند: از اسکن دستگاه‌های در حال تبلیغ تا انتقال داده و قطع اتصال. CBCentralManager به صورت ناهمزمان از طریق دلیگیت CBCentralManagerDelegate کار می‌کند و رویدادهای پشته Bluetooth را به برنامه اطلاع می‌دهد.

راه‌اندازی CBCentralManager فرآیند state restoration را آغاز می‌کند: مدیر وضعیت بلوتوث را در دستگاه بررسی می‌کند و اتصالات قبلی را در صورت بسته شدن برنامه بازیابی می‌کند. فرآیند راه‌اندازی بسته به وضعیت بلوتوث می‌تواند 50 تا 500 میلی‌ثانیه طول بکشد. برنامه باید قبل از شروع هرگونه عملیات BLE منتظر فراخوانی centralManagerDidUpdateState بماند.

معماری Core Bluetooth بر اساس الگوی Delegation ساخته شده است: CBCentralManager پردازش رویدادها (کشف دستگاه‌ها، اتصال، خطاها) را به پروتکل CBCentralManagerDelegate واگذار می‌کند. برای کار با یک Peripheral خاص از پروتکل CBPeripheralDelegate استفاده می‌شود که در مورد کشف سرویس‌ها، ویژگی‌ها و دریافت داده اطلاع‌رسانی می‌کند. این مدل ناهمزمان عملکرد غیرمسدودکننده UI را تضمین می‌کند.

وضعیت‌های CBCentralManager

CBCentralManager از چندین وضعیت عبور می‌کند که تعیین می‌کند آیا پشته BLE برای کار در دسترس است یا خیر. وضعیت از طریق دلیگیت منتقل می‌شود: centralManagerDidUpdateState(_:). توسعه‌دهنده باید همه وضعیت‌ها را مدیریت کند — نه فقط poweredOn، بلکه مواردی که بلوتوث خاموش است یا در دسترس نیست.

وضعیتمعنیاقدام توسعه‌دهنده
.poweredOnبلوتوث روشن و آماده استشروع اسکن
.poweredOffبلوتوث خاموش استنمایش هشدار به کاربر
.unauthorizedبدون مجوزدرخواست مجوز در تنظیمات
.unsupportedدستگاه از BLE پشتیبانی نمی‌کندمخفی کردن قابلیت‌های BLE
.unknownوضعیت نامشخصمنتظر به‌روزرسانی بعدی
.resettingبلوتوث در حال راه‌اندازی مجددمنتظر بازیابی

Unauthorized state از iOS 13+ به طور فزاینده‌ای رایج می‌شود. از این نسخه به بعد، برنامه باید مجوز NSBluetoothAlwaysUsageDescription را در Info.plist داشته باشد. بدون آن، مدیر مرکزی به وضعیت .unauthorized می‌رود و اسکن غیرممکن است. کاربر می‌تواند در هر زمان مجوز را در Settings > Privacy > Bluetooth تغییر دهد.

اسکن دستگاه‌های BLE

scanForPeripherals(withServices:options:) — روش اصلی برای شروع اسکن. پارامتر withServices آرایه‌ای از UUID سرویس‌ها را برای فیلتر کردن دریافت می‌کند: اگر nil ارسال شود، همه دستگاه‌ها کشف می‌شوند که مصرف انرژی را به طور قابل توجهی افزایش می‌دهد. توصیه می‌شود همیشه بر اساس UUID سرویس‌های مورد نیاز برنامه فیلتر کنید. گزینه‌های اسکن شامل CBCentralManagerScanOptionAllowDuplicatesKey (اعلان‌های تکراری درباره یک دستگاه) است.

swift
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") // سرویس باتری

        centralManager.scanForPeripherals(
            withServices: [serviceUUID],
            options: [
                CBCentralManagerScanOptionAllowDuplicatesKey: false
            ]
        )
    }
}

هنگام کشف دستگاه، centralManager(_:didDiscover:advertisementData:rssi:) فراخوانی می‌شود. پارامتر advertisementData شامل دیکشنری کامل داده‌های بسته تبلیغاتی است، از جمله نام دستگاه (CBAdvertisementDataLocalNameKey)، UUID سرویس‌ها (CBAdvertisementDataServiceUUIDsKey) و داده‌های سازنده (CBAdvertisementDataManufacturerDataKey). RSSI — سطح سیگنال بر حسب dBm، قابل دسترسی در لحظه کشف.

اتصال به Peripheral

connect(_:options:) — روشی برای برقراری اتصال BLE با Peripheral کشف شده. پس از فراخوانی connect، iOS سعی می‌کند به دستگاه متصل شود. اتصال موفق با فراخوانی centralManager(_:didConnect:) و خطا با centralManager(_:didFailToConnect:error:) تأیید می‌شود. گزینه‌های اتصال شامل CBConnectPeripheralOptionNotifyOnConnectionKey، CBConnectPeripheralOptionNotifyOnDisconnectionKey و CBConnectPeripheralOptionNotifyOnNotificationKey برای اعلان‌های پس‌زمینه است.

swift
// اتصال به دستگاه BLE
func connectToPeripheral(
    _ peripheral: CBPeripheral
) {
    centralManager.connect(peripheral, options: nil)

    // تنظیم دلیگیت برای Peripheral
    peripheral.delegate = self
}

// دلیگیت: اتصال موفق
func centralManager(
    _ central: CBCentralManager,
    didConnect peripheral: CBPeripheral
) {
    print("متصل به " +
          "\(peripheral.name ?? "unknown")")

    // شروع کشف سرویس
    peripheral.discoverServices(nil)
}

// دلیگیت: خطای اتصال
func centralManager(
    _ central: CBCentralManager,
    didFailToConnect peripheral: CBPeripheral,
    error: Error?
) {
    print("Connection failed: 
          \(error?.localizedDescription ?? "")")
}

مهلت اتصال در iOS 30 ثانیه است. اگر دستگاه در این مدت به درخواست اتصال پاسخ ندهد، didFailToConnect فراخوانی می‌شود. عوامل مؤثر بر مهلت: فاصله تا دستگاه، تداخلات، اینکه آیا دستگاه در حال حاضر در حال تبلیغ است یا خیر. قبل از اتصال مطمئن شوید دستگاه در حالت connectable advertising است (ADV_IND، نه ADV_NONCONN_IND).

کشف سرویس‌ها و ویژگی‌ها

پس از اتصال باید سرویس‌ها (discoverServices) و ویژگی‌ها (discoverCharacteristics) Peripheral کشف شوند. این یک مرحله اجباری قبل از خواندن یا نوشتن داده است. فرآیند ناهمزمان است: discoverServices نتیجه را از طریق peripheral(_:didDiscoverServices:) و discoverCharacteristics از طریق peripheral(_:didDiscoverCharacteristicsFor:error:) برمی‌گرداند.

توصیه می‌شود به جای nil، آرایه‌ای از UUIDهای مورد نظر به discoverServices ارسال شود. فیلتر کردن کشف را سرعت می‌بخشد و در انرژی صرفه‌جویی می‌کند. اگر سرویس یافت نشود، iOS یک آرایه خالی گزارش می‌دهد. پس از کشف ویژگی‌ها، می‌توان مقادیر آنها را خواند (readValue)، در اعلان‌ها مشترک شد (setNotifyValue) یا داده نوشت (writeValue).

نکته مهم: MTU به صورت خودکار توافق می‌شود پس از اتصال. برای دریافت MTU فعلی از peripheral.maximumWriteValueLength(for: .withResponse) یا .withoutResponse استفاده کنید. در iOS حداکثر MTU برای دستگاه‌های BLE 5.0، 512 بایت است. اگر نیاز به انتقال داده بزرگ‌تر از MTU دارید، fragmentation را در سطح برنامه پیاده‌سازی کنید.

اسکن پس‌زمینه و محدودیت‌های iOS

اسکن پس‌زمینه دستگاه‌های BLE در iOS نیاز به پیکربندی ویژه دارد. Core Bluetooth از اجرای پس‌زمینه پشتیبانی می‌کند، اما با محدودیت‌های قابل توجه. برای کار در پس‌زمینه لازم است: bluetooth-central را در Background Modes در Capabilities پروژه فعال کنید، CBCentralManager را با گزینه CBCentralManagerOptionRestoreIdentifierKey برای state restoration راه‌اندازی کنید و رویدادهای مدیر مرکزی را هنگام رفتن به پس‌زمینه پردازش کنید.

محدودیت‌های BLE پس‌زمینه در iOS: scanForPeripherals بدون فیلتر UUID در پس‌زمینه کار نمی‌کند. برنامه باید UUIDهای خاص سرویس‌ها را برای اسکن مشخص کند. iOS ممکن است تحویل رویدادهای BLE را به مدت نامحدود به تأخیر بیندازد. Core Bluetooth به طور خودکار اسکن را هنگام کشف دستگاه منطبق از سر می‌گیرد، حتی اگر برنامه در پس‌زمینه باشد. مهلت اسکن پس‌زمینه: iOS ممکن است برای صرفه‌جویی در انرژی پس از 10-30 دقیقه اسکن را متوقف کند.

State Restoration — مکانیزم Core Bluetooth که امکان بازیابی اتصالات BLE را پس از راه‌اندازی مجدد برنامه یا ریبوت iOS فراهم می‌کند. برای استفاده: CBCentralManagerOptionRestoreIdentifierKey را هنگام راه‌اندازی مشخص کنید، centralManager(_:willRestoreState:) را در دلیگیت پیاده‌سازی کنید و لیست Peripheral‌های متصل را از دیکشنری ارسالی بازیابی کنید. State Restoration — عملکردی حیاتی برای برنامه‌های BLE فعال در پس‌زمینه مانند ردیاب‌های تناسب اندام یا دستگاه‌های پزشکی است.

مدیریت خطا و بازیابی اتصال

CBCentralManager خطاهایی ایجاد می‌کند در چند سناریو: اتصال ناموفق (didFailToConnect)، قطع اتصال (didDisconnectPeripheral)، ویژگی برای خواندن/نوشتن در دسترس نیست (didWriteValue error). همه خطاهای Core Bluetooth از طریق شی Error با دامنه CBErrorDomain بازگردانده می‌شوند. رایج‌ترین کدها: CBErrorConnectionTimeout (0x04)، CBErrorPeripheralDisconnected (0x07)، CBErrorOperationNotSupported (0x0A).

استراتژی بازیابی اتصال: هنگام دریافت didDisconnectPeripheral کد خطا را بررسی کنید. اگر خطا CBErrorConnectionTimeout یا CBErrorPeripheralDisconnected است — اتصال مجدد خودکار را پس از 1-5 ثانیه برنامه‌ریزی کنید. اگر خطا CBErrorOperationNotSupported است — ثبت لاگ کنید و عملیات را تکرار نکنید. برای اتصالات حیاتی (دستگاه‌های پزشکی) از exponential backoff با حداکثر فاصله 60 ثانیه استفاده کنید.

swift
// مدیریت قطع اتصال با اتصال مجدد خودکار
func centralManager(
    _ central: CBCentralManager,
    didDisconnectPeripheral peripheral: CBPeripheral,
    error: Error?
) {
    guard let error = error else {
        return // قطع اتصال مورد انتظار
    }

    print("Disconnected: \(error.localizedDescription)")

    // اتصال مجدد خودکار
    if shouldAutoReconnect {
        DispatchQueue.main.asyncAfter(
            deadline: .now() + reconnectDelay
        ) {
            central.connect(peripheral)
        }
    }
}

هنگام توسعه یک برنامه BLE قابل اعتماد در iOS در نظر بگیرید: Core Bluetooth تحویل همه بسته‌ها را در سیگنال ضعیف تضمین نمی‌کند. برای انتقال قابل اعتماد از writeType .withResponse (نوشتن تأیید شده) استفاده کنید و برای دریافت داده از Peripheral در اعلان‌ها (setNotifyValue) مشترک شوید. برای تشخیص مشکلات اتصال در محیط تولید، لاگ خطاها را نگه دارید.

سوالات متداول

چرا CBCentralManager دستگاه‌ها را شناسایی نمی‌کند؟

وضعیت مدیر را از طریق centralManagerDidUpdateState بررسی کنید. مطمئن شوید مجوز NSBluetoothAlwaysUsageDescription در Info.plist وجود دارد، بلوتوث در دستگاه روشن است و دستگاه پریفرال با نوع صحیح (connectable advertising، نه non-connectable) در حال تبلیغ است.

چند دستگاه BLE می‌توانند همزمان به iOS متصل شوند؟

در دستگاه‌های دارای BLE 5.0 (iPhone 8 و جدیدتر) — تا 7 اتصال همزمان. در دستگاه‌های قدیمی‌تر — تا 3-5. تعداد دستگاه‌های اسکن شده محدود نیست، اما اتصالات فعال دارای محدودیت سختی هستند که توسط Bluetooth Controller تعیین شده است.

چند وقت یکبار می‌توان BLE را در iOS بدون کاهش باتری اسکن کرد؟

توصیه می‌شود با فیلتر UUID اسکن کنید و پس از یافتن دستگاه اسکن را متوقف کنید. اسکن مداوم باتری را تخلیه می‌کند: 1 ساعت اسکن پیوسته حدود 10-15٪ از شارژ iPhone را مصرف می‌کند. از تایمرها و شرایط برای توقف اسکن استفاده کنید.

تفاوت بین CBCentralManager و CBPeripheralManager چیست؟

CBCentralManager — برای اسکن و اتصال به دستگاه‌های BLE خارجی (نقش Central). CBPeripheralManager — برای اینکه دستگاه iOS شما خود به عنوان پریفرال BLE عمل کند (سرویس‌ها را تبلیغ کند). یک نمونه می‌تواند فقط در یک نقش باشد.

چگونه قطع اتصال با دستگاه BLE را مدیریت کنیم؟

centralManager(_:didDisconnectPeripheral:error:) را پیاده‌سازی کنید. اگر خطا nil نیست — اتصال مجدد خودکار را با exponential backoff برنامه‌ریزی کنید (1 ثانیه → 2 → 4 → 8 → حداکثر 60). اگر خطا nil است — دستگاه به طور عادی قطع شده است (مثلاً کاربر دکمه‌ای روی دستگاه را فشار داده است).

خلاصه

  • CBCentralManager — کلاس اصلی Core Bluetooth برای مدیریت اسکن BLE، اتصال و انتقال داده در نقش Central در iOS.
  • اسکن از طریق scanForPeripherals با فیلتر اختیاری UUID سرویس‌ها برای کاهش مصرف انرژی راه‌اندازی می‌شود.
  • اتصال از طریق connect انجام می‌شود، موفقیت با didConnect و خطا با didFailToConnect با مهلت 30 ثانیه تأیید می‌شود.
  • پس از اتصال باید سرویس‌ها و ویژگی‌ها از طریق discoverServices و discoverCharacteristics کشف شوند.
  • اسکن پس‌زمینه نیاز به bluetooth-central Background Mode دارد و با محدودیت‌هایی پشتیبانی می‌شود (فیلتر UUID، تأخیرهای احتمالی).
  • iOS تا 7 اتصال همزمان BLE را در دستگاه‌های دارای BLE 5.0 پشتیبانی می‌کند، state restoration برای بازیابی پس از راه‌اندازی مجدد.
  • مدیریت خطا و اتصال مجدد خودکار با exponential backoff — اساس یک برنامه BLE قابل اعتماد در iOS.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید