Core Bluetooth:iOS 上的 BLE 架构与开发

作者: IT Sectr 发布日期: 2026-07-16 阅读时间: 10 分钟

Core Bluetooth 是 Apple 用于在 iOS、iPadOS 和 macOS 上与 Bluetooth Low Energy 交互的框架。该框架提供了一整套 API,用于在 BLE 的两种角色中工作:中央设备 (CBCentralManager) 用于扫描和连接外围设备,以及外围设备 (CBPeripheralManager) 用于模拟 BLE 服务器。Core Bluetooth 将 BLE 协议栈从物理无线电抽象到应用 GATT 配置文件。根据 Apple Developer,2026,Core Bluetooth 是 Apple 唯一官方的 BLE 开发 API,支持 BLE 4.0–5.4,具有 extended advertising、2M PHY 和 LE Audio。

要点

  • Core Bluetooth — Apple 用于在 iOS、iPadOS 和 macOS 上进行 BLE 开发的系统框架
  • CBCentralManager — 用于从中央设备端扫描和连接 BLE 外围设备的类
  • CBPeripheralManager — 用于创建发布服务和特性的 BLE 服务器的类
  • GATT 配置文件 — 用于数据交换的服务、特性和描述符的分层模型
  • 后台模式 — Core Bluetooth 通过系统委托和状态恢复支持后台 BLE 通信

什么是 Core Bluetooth:架构与组件

Core Bluetooth 将 BLE 协议栈分为由 Bluetooth SIG 规范定义的两个逻辑角色。中央设备角色 (Central) 由 CBCentralManager 类表示 — 它启动扫描、建立连接并管理已连接 CBPeripheral 的列表。外围设备角色 (Peripheral) 由 CBPeripheralManager 表示 — 它发布服务和特性、响应中央的请求并发送通知。一个 iOS 会话可以同时在多个 BLE 无线电上以两种角色工作,但典型应用使用一种角色。

Core Bluetooth 架构包括五个关键抽象。 CBCentralManager 管理设备蓝牙适配器的状态:poweredOn(准备就绪)、poweredOff(蓝牙已关闭)、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。如果状态不是 .poweredOn,系统将忽略任何 BLE 调用。开发人员必须在每次扫描和连接之前检查状态。从 .poweredOff 到 .poweredOn 的转换在 iOS 设置中打开蓝牙时发生 — 委托收到重复调用,应用可以恢复扫描。

CBCentralManager:扫描和连接 BLE 设备

CBCentralManager — 从中央设备端进行所有 BLE 操作的入口点。初始化接受一个委托 (CBCentralManagerDelegate) 和一个 DispatchQueue 队列 — Apple 建议使用 main queue 以简化或 serial queue 以提高性能。初始化后,框架自动检查蓝牙状态并调用 centralManagerDidUpdateState: — 第一个需要处理的必需委托。

扫描通过 scanForPeripheralsWithServices:options: 方法启动。第一个参数是用于过滤的 CBUUID 服务数组:如果已知感兴趣服务的 UUID,传递它们可以减少能耗和搜索时间。如果为 nil,则检测范围内的所有 BLE 设备。选项包括 .allowDuplicatesKey(重复检测同一设备)和 .solicitedServiceUUIDsKey(用于在中央上发布的服务)。

swift
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("蓝牙不可用")
            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 启动扫描。didDiscoverPeripheral 将找到的设备收集到 discoveredPeripherals 数组中,并根据标识符进行去重。连接后 (didConnect),立即启动服务发现 — 这是任何 GATT 操作之前的必需步骤。

CBPeripheralManager:在 iOS 上创建 BLE 服务器

CBPeripheralManager — 用于在 iOS 上模拟 BLE 外围设备的类。处于外围角色中的应用可以发布自己的服务和特性,接收来自中央设备的传入读/写请求,并发送通知。CBPeripheralManager 用于由 iPhone 模拟的 BLE 配件:遥控器、键盘、追踪器、IoT 网关。

CBPeripheralManager 的生命周期从初始化和 CBPeripheralManagerDelegate 委托开始。通过 peripheralManagerDidUpdateState: 确认 poweredOn 后,发布服务 (addService:) 并启动广播 (startAdvertising:)。CBAdvertisementData 广播数据包括本地名称 (CBAdvertisementDataLocalNameKey)、服务 UUID (CBAdvertisementDataServiceUUIDsKey) 和功率级别 (CBAdvertisementDataTxPowerLevelKey)。广播包最大大小为 BLE 4.0 为 31 字节,BLE 5.0+ extended advertising 为 251 字节。

swift
// 通过 CBPeripheralManager 在 iOS 上实现 BLE 外围设备
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 操作:读取、写入和通知

GATT 操作(通用属性协议) — Core Bluetooth 中数据交换的基础。发现服务和特性后,中央设备可以执行三种类型的操作:读取特性值、写入值和订阅通知/指示。每个操作都是异步的,并通过相应的 CBPeripheralDelegate 委托返回结果。

读取 通过调用 readValueForCharacteristic: 执行。值在 peripheral:didUpdateValueForCharacteristic:error: 中到达。重要提示:读取返回来自设备的当前值,而不是缓存值。如果设备不支持读取 (.read 属性),调用将返回错误。对于大值(大于 MTU),BLE 在 GATT 级别自动分段和组装数据。

写入 通过 writeValue:forCharacteristic:type: 执行。BLE 支持两种写入模式:withResponse(可靠,带确认)和 withoutResponse(快速,无确认)。CBCharacteristic.properties 属性确定可用的写入类型。单个写入包的最大大小受 MTU 限制:BLE 4.0 为 23 字节(20 字节有效数据 + 3 字节标头),BLE 5.0 具有 extended MTU 为 247 字节(MTU 251)。

通知 通过调用 setNotifyValue:true forCharacteristic: 激活。订阅后,每当特性值更改时,外围设备通过 peripheral:didUpdateValueForCharacteristic: 自动发送更新。要禁用通知,调用 setNotifyValue:false forCharacteristic:。Core Bluetooth 自动管理外围设备上的 CCCD 描述符。

操作方法委托传输类型
读取readValueForCharacteristic:didUpdateValueForCharacteristic轮询(请求-响应)
写入 withResponsewriteValue:forCharacteristic:type:withResponsedidWriteValueForCharacteristic带确认
写入 withoutResponsewriteValue:forCharacteristic:type:withoutResponse无委托无确认
通知setNotifyValue:true forCharacteristic:didUpdateNotificationStateForCharacteristic + didUpdateValueForCharacteristic来自外围设备的推送

Core Bluetooth 后台模式与状态恢复

后台模式 Core Bluetooth 允许 BLE 应用在后台继续扫描、保持连接和接收通知。激活需要:在 Xcode 中启用 capability “Uses Bluetooth LE accessories” (Info.plist → Required background modes → App communicates using Core Bluetooth) 并将 „bluetooth-central” 键添加到 UIBackgroundModes。对于外围角色 — „bluetooth-peripheral”。

状态恢复 — Core Bluetooth 的机制,用于在 iOS 系统重启应用后恢复 BLE 连接状态。当激活后台模式并在 CBCentralManager 或 CBPeripheralManager 初始化中指定 restoreIdentifier 时,iOS 在应用终止时保存 BLE 协议栈状态,并在下次启动时恢复。委托 centralManager:willRestoreState: 接收一个包含已保存 CBPeripheral 和待处理连接的字典。

swift
// 具有状态恢复功能的 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("恢复后蓝牙准备就绪")
        }
    }
}

BLECentralWithRestoration 配置中,CBCentralManagerOptionRestoreIdentifierKey 键激活状态保存。如果应用被 iOS 终止(例如由于内存不足),下次启动时 centralManager:willRestoreState: 接收先前连接的 CBPeripheral 列表。应用恢复委托并重新发现服务 — 用户不会注意到连接中断。没有状态恢复,所有 BLE 会话在应用终止时丢失。

Swift 中 BLE 应用示例:中央与外围

完整示例 Swift 中的 BLE 应用将中央和外围设备结合在一个项目中。应用可以在两种模式下工作:检测并连接 BLE 设备(中央)或模拟 BLE 配件(外围)。下面呈现了具有在启动时选择角色的通用 BLE 管理器的架构。

swift
// 用于中央和外围的通用 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 管理器在初始化时选择角色并创建相应的 Manager(CBCentralManager 或 CBPeripheralManager)。角色标志可以存储在 UserDefaults 中或通过配置服务器传递。这种方法允许 BLE 应用适应使用场景:在销售点,iPhone 作为中央扫描支付终端,在 IoT 网关上 — 作为外围从传感器收集数据。

常见问题

什么是 Core Bluetooth?

Core Bluetooth — Apple 用于在 iOS、iPadOS 和 macOS 上进行 BLE 开发的框架。为中央 (CBCentralManager) 和外围 (CBPeripheralManager) 设备的操作提供 API。支持 BLE 4.0–5.4、extended advertising、2M PHY 和 LE Audio。Core Bluetooth 是 Apple 唯一官方的 BLE 通信 API,对于所有使用 Bluetooth Low Energy 的 iOS 应用都是必需的。

CBCentralManager 和 CBPeripheralManager 有什么区别?

CBCentralManager — 用于在中央设备角色中工作的类:扫描 BLE 外围设备、建立连接、读取和写入特性。 CBPeripheralManager — 用于在外围角色中工作的类:发布服务、响应读/写请求和发送通知。一部 iPhone 可以通过不同的管理器实例同时在两个角色中工作。

如何配置 Core Bluetooth 以便在后台工作?

对于 BLE 后台工作,在 Xcode 中启用 capability „Uses Bluetooth LE accessories” 并将 „bluetooth-central” 键添加到 UIBackgroundModes。对于外围角色 — „bluetooth-peripheral”。在管理器初始化时指定 restoreIdentifier 以进行状态恢复。没有这些设置,后台应用不会收到 BLE 事件并失去连接。

为什么 Core Bluetooth 找不到设备?

主要原因:CBCentralManager.state != .poweredOn(蓝牙已关闭或未授权)、委托未设置、设备超出范围或不发送广播包。检查 Info.plist 中的 NSBluetoothAlwaysUsageDescription 权限、centralManagerDidUpdateState 中的蓝牙状态,并确保 scanForPeripherals 仅在 .poweredOn 时调用。

可以同时连接多个 CBPeripheral 吗?

是的,Core Bluetooth 支持同时连接到多个 BLE 设备。每个 CBPeripheral 通过自己的委托独立管理。iOS 在系统级别限制同时 BLE 连接的数量(iPhone 通常为 5–7)。对于 1:N 场景(例如,具有 10 个追踪器的健身中心),需要排队和循环服务外围设备。

总结

  • Core Bluetooth — Apple 用于 BLE 开发的系统框架,包含 CBCentralManager 和 CBPeripheralManager 类
  • CBCentralManager 管理与远程 BLE 设备的扫描、连接和 GATT 操作
  • CBPeripheralManager 通过发布服务和处理传入请求来模拟 BLE 外围设备
  • GATT 配置文件 包括服务、特性和描述符,具有读取、写入和通知操作
  • 后台模式 需要 UIBackgroundModes 和 restoreIdentifier 以实现状态恢复
  • MTU BLE 限制数据包大小:BLE 4.0 为 23 字节,BLE 5.0+ 具有 extended MTU 为 251 字节
  • Swift async/await 通过 CheckedContinuation 简化了具有委托的异步 BLE 代码

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读