Core Bluetooth: kiến trúc và phát triển BLE trên iOS

Tác giả: IT Sectr Đã đăng: 2026-07-16 Thời gian đọc: 10 phút

Core Bluetooth là framework của Apple để tương tác với Bluetooth Low Energy trên iOS, iPadOS và macOS. Framework cung cấp một bộ API hoàn chỉnh để hoạt động trong cả hai vai trò BLE: thiết bị trung tâm (CBCentralManager) để quét và kết nối với thiết bị ngoại vi, và thiết bị ngoại vi (CBPeripheralManager) để mô phỏng một máy chủ BLE. Core Bluetooth trừu tượng hóa ngăn xếp giao thức BLE từ bộ đàm vật lý đến hồ sơ GATT ở cấp ứng dụng. Theo Apple Developer, 2026, Core Bluetooth là API chính thức duy nhất của Apple cho phát triển BLE, hỗ trợ BLE 4.0–5.4 với extended advertising, 2M PHY và LE Audio.

Những điểm chính

  • Core Bluetooth — framework hệ thống của Apple cho phát triển BLE trên iOS, iPadOS và macOS
  • CBCentralManager — lớp để quét và kết nối với thiết bị ngoại vi BLE từ phía thiết bị trung tâm
  • CBPeripheralManager — lớp để tạo máy chủ BLE xuất bản dịch vụ và đặc tính
  • Hồ sơ GATT — mô hình phân cấp của dịch vụ, đặc tính và bộ mô tả để trao đổi dữ liệu
  • Chế độ nền — Core Bluetooth hỗ trợ giao tiếp BLE trong nền thông qua ủy quyền hệ thống và khôi phục trạng thái

Core Bluetooth là gì: kiến trúc và thành phần

Core Bluetooth chia ngăn xếp BLE thành hai vai trò logic được xác định bởi đặc tả Bluetooth SIG. Vai trò thiết bị trung tâm (Central) được đại diện bởi lớp CBCentralManager — nó bắt đầu quét, thiết lập kết nối và quản lý danh sách CBPeripheral đã kết nối. Vai trò thiết bị ngoại vi (Peripheral) được đại diện bởi CBPeripheralManager — nó xuất bản dịch vụ và đặc tính, trả lời các yêu cầu trung tâm và gửi thông báo. Một phiên iOS có thể hoạt động đồng thời trong cả hai vai trò trên các bộ đàm BLE khác nhau, nhưng ứng dụng điển hình sử dụng một vai trò.

Kiến trúc Core Bluetooth bao gồm năm trừu tượng chính. CBCentralManager quản lý trạng thái bộ chuyển đổi Bluetooth của thiết bị: poweredOn (sẵn sàng hoạt động), poweredOff (Bluetooth tắt), unauthorized (không có quyền), unsupported (BLE không khả dụng). CBPeripheral đại diện cho thiết bị BLE từ xa với UUID, tên, RSSI và hệ phân cấp GATT. CBService — một nhóm logic của các đặc tính. CBCharacteristic — một điểm dữ liệu cho đọc/ghi/thông báo. CBPeripheralManager tạo một máy chủ GATT cục bộ để mô phỏng thiết bị ngoại vi.

LớpVai tròPhương thức chính
CBCentralManagerThiết bị trung tâmscanForPeripherals, connect, cancelPeripheralConnection, retrievePeripherals
CBPeripheralNgoại vi từ xadiscoverServices, discoverCharacteristics, readValue, writeValue, setNotifyValue
CBPeripheralManagerNgoại vi cục bộaddService, removeService, startAdvertising, respondToRequest, updateValue
CBCentralTrung tâm từ xamaximumUpdateValueLength, identifier, ancsAuthorized

Trạng thái CBCentralManager kiểm soát tất cả các thao tác BLE. Khi ứng dụng khởi động, centralManagerDidUpdateState được gọi với trạng thái Bluetooth hiện tại. Nếu trạng thái không phải .poweredOn, hệ thống sẽ bỏ qua mọi lệnh gọi BLE. Nhà phát triển phải kiểm tra trạng thái trước mỗi lần quét và kết nối. Quá trình chuyển từ .poweredOff sang .poweredOn xảy ra khi Bluetooth được bật trong Cài đặt iOS — ủy quyền nhận được lệnh gọi lặp lại và ứng dụng có thể tiếp tục quét.

CBCentralManager: quét và kết nối thiết bị BLE

CBCentralManager là điểm vào cho tất cả các thao tác BLE từ phía thiết bị trung tâm. Khởi tạo nhận một ủy quyền (CBCentralManagerDelegate) và một DispatchQueue — Apple khuyên dùng hàng đợi chính để đơn giản hoặc hàng đợi tuần tự để hiệu suất. Sau khi khởi tạo, framework tự động kiểm tra trạng thái Bluetooth và gọi centralManagerDidUpdateState: — ủy quyền bắt buộc đầu tiên cần xử lý.

Quét bắt đầu với phương thức scanForPeripheralsWithServices:options:. Tham số đầu tiên là mảng các CBUUID dịch vụ để lọc: nếu UUID của các dịch vụ mong muốn được biết, việc truyền chúng sẽ giảm mức tiêu thụ điện và thời gian tìm kiếm. Nếu là nil, tất cả các thiết bị BLE trong phạm vi sẽ được phát hiện. Các tùy chọn bao gồm .allowDuplicatesKey (phát hiện lặp lại cùng một thiết bị) và .solicitedServiceUUIDsKey (cho các dịch vụ được xuất bản trên trung tâm).

swift
import CoreBluetooth

class BLECentral: NSObject {

    private var centralManager: CBCentralManager!
    private var discoveredPeripherals: [CBPeripheral] = []

    override init() {
        super.init()
        centralManager = CBCentralManager(delegate: self, queue: .main)
    }

    // Bắt đầu quét BLE
    func startScan() {
        guard centralManager.state == .poweredOn else {
            print("Bluetooth không khả dụng")
            return
        }
        // Quét tất cả thiết bị (nil = không lọc)
        centralManager.scanForPeripherals(withServices: nil,
                                            options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
    }

    // Dừng quét
    func stopScan() {
        centralManager.stopScan()
    }

    // Kết nối đến thiết bị đã chọn
    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)")
    }
}

Lớp BLECentral minh họa chu kỳ đầy đủ của việc quét và kết nối thiết bị BLE. centralManagerDidUpdateState bắt đầu quét khi Bluetooth được bật. didDiscoverPeripheral thu thập các thiết bị được tìm thấy vào mảng discoveredPeripherals với loại bỏ trùng lặp theo identifier. Sau khi kết nối (didConnect), việc khám phá dịch vụ bắt đầu ngay lập tức — đây là bước bắt buộc trước bất kỳ thao tác GATT nào.

CBPeripheralManager: tạo máy chủ BLE trên iOS

CBPeripheralManager là lớp để mô phỏng thiết bị ngoại vi BLE trên iOS. Ứng dụng trong vai trò ngoại vi có thể xuất bản dịch vụ và đặc tính của mình, chấp nhận các yêu cầu đọc/ghi đến từ thiết bị trung tâm và gửi thông báo. CBPeripheralManager được sử dụng cho các phụ kiện BLE được mô phỏng bởi iPhone: điều khiển từ xa, bàn phím, trình theo dõi, cổng IoT.

Vòng đời của CBPeripheralManager bắt đầu bằng khởi tạo và ủy quyền CBPeripheralManagerDelegate. Sau khi nhận được xác nhận poweredOn qua peripheralManagerDidUpdateState:, các dịch vụ được xuất bản (addService:) và quảng cáo được bắt đầu (startAdvertising:). Dữ liệu quảng cáo CBAdvertisementData bao gồm tên cục bộ (CBAdvertisementDataLocalNameKey), UUID dịch vụ (CBAdvertisementDataServiceUUIDsKey) và mức công suất truyền (CBAdvertisementDataTxPowerLevelKey). Kích thước gói quảng cáo tối đa là 31 byte cho BLE 4.0, 251 byte cho extended advertising BLE 5.0+.

swift
// Thiết bị ngoại vi BLE trên iOS qua 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)
    }

    // Xuất bản dịch vụ với đặc tính
    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)
    }

    // Bắt đầu quảng cáo
    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()
        }
    }

    // Xử lý yêu cầu đọc
    func peripheralManager(_ peripheral: CBPeripheralManager,
                        didReceiveRead request: CBATTRequest) {
        let data = "CurrentValue".data(using: .utf8)!
        request.value = data
        peripheralManager.respond(to: request, withResult: .success)
    }

    // Xử lý yêu cầu ghi
    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)
    }
}

Lớp BLEPeripheral tạo một máy chủ BLE với một đặc tính duy nhất hỗ trợ đọc, ghi và thông báo. Sau khi khởi tạo, peripheralManagerDidUpdateState xuất bản dịch vụ qua addService:, sau đó bắt đầu quảng cáo qua startAdvertising:. Các trình xử lý didReceiveRead và didReceiveWrite trả lời các yêu cầu GATT đến từ thiết bị trung tâm. Phương thức updateValue:forCharacteristic:onSubscribedCentrals: được sử dụng để gửi thông báo.

Thao tác GATT: đọc, ghi và thông báo

Các thao tác GATT (Generic Attribute Profile) là nền tảng trao đổi dữ liệu trong Core Bluetooth. Sau khi khám phá dịch vụ và đặc tính, thiết bị trung tâm có thể thực hiện ba loại thao tác: đọc giá trị đặc tính, ghi giá trị và đăng ký nhận thông báo/chỉ thị. Mỗi thao tác là bất đồng bộ và trả về kết quả thông qua callback CBPeripheralDelegate tương ứng.

Đọc: được thực hiện bằng cách gọi readValueForCharacteristic:. Giá trị đến trong peripheral:didUpdateValueForCharacteristic:error:. Quan trọng: đọc trả về giá trị hiện tại từ thiết bị, không phải giá trị đã lưu trong bộ nhớ đệm. Nếu thiết bị không hỗ trợ đọc (thuộc tính .read), lệnh gọi sẽ trả về lỗi. Đối với các giá trị lớn (lớn hơn MTU), BLE tự động phân mảnh và tái hợp dữ liệu ở cấp GATT.

Ghi: được thực hiện bằng cách gọi writeValue:forCharacteristic:type:. BLE hỗ trợ hai mô hình ghi: withResponse (đáng tin cậy, có xác nhận) và withoutResponse (nhanh, không xác nhận). Thuộc tính CBCharacteristic.properties xác định các loại ghi có sẵn. Kích thước tối đa của một gói ghi duy nhất bị giới hạn bởi MTU: 23 byte cho BLE 4.0 (20 byte dữ liệu + 3 byte tiêu đề), lên đến 247 byte cho BLE 5.0 với MTU mở rộng (MTU 251).

Thông báo: được kích hoạt bằng cách gọi setNotifyValue:true forCharacteristic:. Sau khi đăng ký, thiết bị ngoại vi tự động gửi cập nhật qua peripheral:didUpdateValueForCharacteristic: bất cứ khi nào giá trị đặc tính thay đổi. Để tắt thông báo, gọi setNotifyValue:false forCharacteristic:. Core Bluetooth tự động quản lý bộ mô tả CCCD trên thiết bị ngoại vi.

Thao tácPhương thứcỦy quyềnLoại truyền
ĐọcreadValueForCharacteristic:didUpdateValueForCharacteristicThăm dò (yêu cầu-phản hồi)
Ghi withResponsewriteValue:forCharacteristic:type:withResponsedidWriteValueForCharacteristicCó xác nhận
Ghi withoutResponsewriteValue:forCharacteristic:type:withoutResponseKhông có ủy quyềnKhông xác nhận
Thông báosetNotifyValue:true forCharacteristic:didUpdateNotificationStateForCharacteristic + didUpdateValueForCharacteristicPush từ thiết bị ngoại vi

Chế độ nền Core Bluetooth và State Restoration

Chế độ nền trong Core Bluetooth cho phép các ứng dụng BLE tiếp tục quét, duy trì kết nối và nhận thông báo khi ở chế độ nền. Để kích hoạt, hãy bật khả năng “Uses Bluetooth LE accessories” trong Xcode (Info.plist → Required background modes → App communicates using Core Bluetooth) và thêm khóa “bluetooth-central” vào UIBackgroundModes. Cho vai trò ngoại vi — “bluetooth-peripheral”.

State Restoration là một cơ chế của Core Bluetooth để khôi phục trạng thái kết nối BLE sau khi ứng dụng khởi động lại bởi iOS. Khi chế độ nền đang hoạt động và restoreIdentifier được chỉ định trong khởi tạo CBCentralManager hoặc CBPeripheralManager, iOS lưu trạng thái ngăn xếp BLE khi ứng dụng kết thúc và khôi phục nó ở lần khởi động tiếp theo. Ủy quyền centralManager:willRestoreState: nhận một từ điển với các CBPeripheral đã lưu và các kết nối đang chờ.

swift
// Cấu hình Core Bluetooth với State Restoration
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 {

    // Khôi phục trạng thái sau khi khởi động lại
    func centralManager(_ central: CBCentralManager,
                        willRestoreState dict: [String : Any]) {
        if let peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey]
            as? [CBPeripheral] {
            for peripheral in peripherals {
                peripheral.delegate = self
                // Khôi phục khám phá GATT
                peripheral.discoverServices(nil)
            }
        }
    }

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOn {
            print("Bluetooth sẵn sàng sau khi khôi phục")
        }
    }
}

Trong cấu hình BLECentralWithRestoration, khóa CBCentralManagerOptionRestoreIdentifierKey kích hoạt lưu trữ trạng thái. Nếu ứng dụng bị iOS kết thúc (ví dụ, do thiếu bộ nhớ), ở lần khởi động tiếp theo centralManager:willRestoreState: nhận danh sách các CBPeripheral đã kết nối trước đó. Ứng dụng khôi phục các ủy quyền và thực hiện khám phá lại dịch vụ — người dùng không nhận thấy sự gián đoạn kết nối. Nếu không có State Restoration, tất cả các phiên BLE sẽ bị mất khi ứng dụng kết thúc.

Ví dụ ứng dụng BLE trong Swift: trung tâm và ngoại vi

Một ví dụ hoàn chỉnh về ứng dụng BLE trong Swift kết hợp cả thiết bị trung tâm và ngoại vi trong một dự án. Ứng dụng có thể hoạt động ở hai chế độ: khám phá và kết nối với thiết bị BLE (Trung tâm) hoặc mô phỏng phụ kiện BLE (Ngoại vi). Dưới đây là kiến trúc với trình quản lý BLE chung chọn vai trò khi khởi động.

swift
// Trình quản lý BLE phổ quát cho trung tâm và ngoại vi
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)
        }
    }

    // Thiết bị trung tâm: quét
    func scanForDevices() {
        centralManager?.scanForPeripherals(withServices: nil, options: nil)
    }

    // Thiết bị ngoại vi: quảng cáo
    func advertiseService() {
        let data: [String: Any] = [
            CBAdvertisementDataServiceUUIDsKey: [advertisedServiceUUID]
        ]
        peripheralManager?.startAdvertising(data)
    }
}

// Sử dụng khi khởi động
let isCentral = UserDefaults.standard.bool(forKey: "isCentral")
let manager = BLEManager(role: isCentral ? .central : .peripheral)

if isCentral {
    manager.scanForDevices()
} else {
    manager.advertiseService()
}

BLEManager chọn vai trò khi khởi tạo và tạo trình quản lý tương ứng (CBCentralManager hoặc CBPeripheralManager). Cờ vai trò có thể được lưu trong UserDefaults hoặc truyền qua máy chủ cấu hình. Cách tiếp cận này cho phép ứng dụng BLE thích ứng với trường hợp sử dụng: tại điểm bán hàng, iPhone hoạt động như trung tâm để quét thiết bị thanh toán; trên cổng IoT — như ngoại vi để thu thập dữ liệu từ cảm biến.

Câu hỏi thường gặp

Core Bluetooth là gì?

Core Bluetooth là framework của Apple cho phát triển BLE trên iOS, iPadOS và macOS. Nó cung cấp API cho cả thiết bị trung tâm (CBCentralManager) và ngoại vi (CBPeripheralManager). Nó hỗ trợ BLE 4.0–5.4, extended advertising, 2M PHY và LE Audio. Core Bluetooth là API chính thức duy nhất của Apple cho giao tiếp BLE, cần thiết cho tất cả ứng dụng iOS làm việc với Bluetooth Low Energy.

Sự khác biệt giữa CBCentralManager và CBPeripheralManager là gì?

CBCentralManager là lớp cho vai trò thiết bị trung tâm: nó quét các thiết bị ngoại vi BLE, thiết lập kết nối, đọc và ghi các đặc tính. CBPeripheralManager là lớp cho vai trò ngoại vi: nó xuất bản dịch vụ, trả lời yêu cầu đọc/ghi và gửi thông báo. Một iPhone có thể hoạt động trong cả hai vai trò đồng thời thông qua các thể hiện trình quản lý khác nhau.

Làm thế nào để cấu hình Core Bluetooth cho hoạt động nền?

Để hoạt động BLE nền, hãy bật khả năng “Uses Bluetooth LE accessories” trong Xcode và thêm khóa “bluetooth-central” vào UIBackgroundModes. Cho vai trò ngoại vi — “bluetooth-peripheral”. Chỉ định restoreIdentifier khi khởi tạo trình quản lý để State Restoration. Nếu không có cài đặt này, ứng dụng ở chế độ nền sẽ không nhận được sự kiện BLE và sẽ mất kết nối.

Tại sao Core Bluetooth không tìm thấy thiết bị?

Nguyên nhân phổ biến: CBCentralManager.state != .poweredOn (Bluetooth tắt hoặc không được ủy quyền), ủy quyền chưa được đặt, thiết bị ngoài phạm vi hoặc không gửi gói quảng cáo. Kiểm tra quyền NSBluetoothAlwaysUsageDescription trong Info.plist, trạng thái Bluetooth trong centralManagerDidUpdateState và đảm bảo scanForPeripherals chỉ được gọi khi .poweredOn.

Có thể kết nối nhiều CBPeripheral đồng thời không?

Có, Core Bluetooth hỗ trợ kết nối đồng thời với nhiều thiết bị BLE. Mỗi CBPeripheral được quản lý độc lập thông qua ủy quyền riêng của nó. iOS giới hạn số lượng kết nối BLE đồng thời ở cấp hệ thống (thường là 5–7 cho iPhone). Đối với các kịch bản 1:N (ví dụ, trung tâm thể hình với 10 thiết bị theo dõi), cần xếp hàng đợi và phục vụ theo chu kỳ các thiết bị ngoại vi.

Tổng kết

  • Core Bluetooth — framework hệ thống của Apple cho phát triển BLE với các lớp CBCentralManager và CBPeripheralManager
  • CBCentralManager quản lý việc quét, kết nối và thao tác GATT với các thiết bị BLE từ xa
  • CBPeripheralManager mô phỏng thiết bị ngoại vi BLE với xuất bản dịch vụ và xử lý yêu cầu đến
  • Hồ sơ GATT bao gồm dịch vụ, đặc tính và bộ mô tả với các thao tác đọc, ghi và thông báo
  • Chế độ nền yêu cầu UIBackgroundModes và restoreIdentifier cho State Restoration
  • MTU giới hạn kích thước gói BLE: 23 byte cho BLE 4.0, lên đến 251 byte cho BLE 5.0+ với MTU mở rộng
  • Swift async/await qua CheckedContinuation đơn giản hóa mã BLE bất đồng bộ với ủy quyền

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm