文章目录
-
-
- [🧱 核心概念:你需要了解的四个关键词](#🧱 核心概念:你需要了解的四个关键词)
- [🚀 开发实战:如何用你的iPhone连接一个BLE设备](#🚀 开发实战:如何用你的iPhone连接一个BLE设备)
-
- [1. 前期准备:导入框架与申请权限](#1. 前期准备:导入框架与申请权限)
- [2. 初始化中心管理器并检查蓝牙状态](#2. 初始化中心管理器并检查蓝牙状态)
- [3. 扫描外围设备](#3. 扫描外围设备)
- [4. 连接外围设备](#4. 连接外围设备)
- [5. 发现服务与特征](#5. 发现服务与特征)
- [6. 读写数据与订阅通知](#6. 读写数据与订阅通知)
- [💎 总结与最佳实践](#💎 总结与最佳实践)
-
学习 iOS 的 CoreBluetooth 框架,主要是为了开发能与 蓝牙低功耗(BLE) 设备通信的 App。它不支持经典蓝牙的详细开发,比如连接蓝牙耳机。
下面是一份学习教程,会从核心概念讲起,再通过一个中心设备的完整开发流程,带你一步步上手。
🧱 核心概念:你需要了解的四个关键词
在开始编码前,先理解 CoreBluetooth 框架中的四个核心角色,这是后续开发的基础。
- CBCentralManager (中心设备):你的 iPhone,作为"中心",主动扫描和连接其他蓝牙设备。
- CBPeripheral (外围设备):你连接的蓝牙设备,如心率手环、智能灯泡,作为"外围"提供数据或服务。
- CBService (服务) :外围设备能提供的某种功能,比如"心率监测服务"。
- CBCharacteristic (特征) :服务里的具体数据点,比如"心率数值"这个特征,数据就是通过读写特征来完成的。
🚀 开发实战:如何用你的iPhone连接一个BLE设备
下面以最常见的中心模式(Central) 为例,展示如何让 iPhone 扫描、连接并读取一个 BLE 设备的数据。
1. 前期准备:导入框架与申请权限
- 导入框架 :在需要用到蓝牙的 Swift 文件顶部,加入
import CoreBluetooth。 - 申请权限 :在
Info.plist文件中,添加NSBluetoothAlwaysUsageDescription键,并填写向用户申请蓝牙权限时的提示语。
2. 初始化中心管理器并检查蓝牙状态
创建一个类,通常命名为 BluetoothManager,并遵循 CBCentralManagerDelegate 协议。
swift
import CoreBluetooth
class BluetoothManager: NSObject, CBCentralManagerDelegate {
var centralManager: CBCentralManager!
override init() {
super.init()
// 初始化中心管理器,代理设置为 self,队列设为 nil 表示在主线程回调
centralManager = CBCentralManager(delegate: self, queue: nil)
}
// 必须实现的代理方法,用于检查蓝牙状态
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .poweredOn:
print("蓝牙已开启,可以开始扫描")
// 在这里可以调用开始扫描的方法
case .poweredOff:
print("蓝牙未开启,请打开蓝牙")
case .unsupported:
print("设备不支持蓝牙")
default:
print("蓝牙状态未知")
}
}
}
3. 扫描外围设备
在蓝牙状态确认为 .poweredOn 后,调用 scanForPeripherals 方法开始扫描。
swift
func startScanning() {
// withServices: nil 表示扫描所有设备,传入特定服务的 UUID 数组可以过滤结果
// CBCentralManagerScanOptionAllowDuplicatesKey: false 表示不重复发现同一设备
centralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: false])
}
当扫描到设备时,会触发代理方法 didDiscover。
swift
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
print("发现设备: \(peripheral.name ?? "未知设备"), 信号强度: \(RSSI)")
// 假设我们想连接名为 "MyDevice" 的设备
if peripheral.name == "MyDevice" {
// 找到目标设备后,停止扫描以节省电量
centralManager.stopScan()
// 发起连接
centralManager.connect(peripheral, options: nil)
}
}
4. 连接外围设备
连接的结果会通过以下代理方法反馈。
swift
// 连接成功
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
print("成功连接设备: \(peripheral.name ?? "未知设备")")
// 设置外围设备的代理,以便接收其服务、特征等信息
peripheral.delegate = self
// 开始发现设备提供的所有服务,传入 nil 表示发现所有服务
peripheral.discoverServices(nil)
}
// 连接失败
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
print("连接设备失败: \(error?.localizedDescription ?? "未知错误")")
}
5. 发现服务与特征
连接成功后,需要发现设备提供的服务,以及每个服务下的特征。这一步需要遵循 CBPeripheralDelegate 协议。
swift
extension BluetoothManager: CBPeripheralDelegate {
// 发现服务
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
guard let services = peripheral.services else { return }
for service in services {
print("发现服务: \(service.uuid)")
// 发现该服务下的所有特征,传入 nil 表示发现所有特征
peripheral.discoverCharacteristics(nil, for: service)
}
}
// 发现特征
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
guard let characteristics = service.characteristics else { return }
for characteristic in characteristics {
print("发现特征: \(characteristic.uuid)")
// 在这里可以对感兴趣的特征进行读取、写入或订阅通知
}
}
}
6. 读写数据与订阅通知
发现特征后,就可以进行数据交互了。
- 读取数据 :
peripheral.readValue(for: characteristic) - 写入数据 :
peripheral.writeValue(data, for: characteristic, type: .withResponse)。withResponse表示需要设备确认。 - 订阅通知 :
peripheral.setNotifyValue(true, for: characteristic)。当特征值发生变化时,设备会主动发送通知,并在peripheral(_:didUpdateValueFor:error:)代理方法中接收。
💎 总结与最佳实践
- 注意线程安全 :确保 UI 更新在主线程,可使用
DispatchQueue.main.async {}。 - 实现错误处理和重试:蓝牙通信不稳定,代码要有重试和错误处理机制。
- 优化扫描策略 :找到目标设备后立即停止扫描,并通过
withServices:参数过滤设备。 - 处理大数据传输:BLE 单次数据包有限制,大数据需分包发送和重组。
- 处理后台模式 :若需后台使用蓝牙,需在 Capabilities 中开启
Uses Bluetooth LE accessories。
总的来说,学习 CoreBluetooth 最好的方法就是动手实践。可以从一个简单的"设备扫描器"开始,逐步加入连接、读写功能。遇到问题多查阅官方文档和社区资料,祝你学习顺利!