iOS之蓝牙的使用与注意

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

最近在项目有使用到低功耗蓝牙相关的,所以在此写一下蓝牙的使用及使用中遇到的问题,如果文中有问题的话,欢迎各位掘友指正。

一般我们使用蓝牙的主要流程通常如下:

  • 开始一个中心管理对象
  • 发现并且连接广告中的设备
  • 在连接设备之后扫描数据。
  • 针对设备服务的特征发送读写请求
  • 订阅支持notified(在数据更新时会主动上报)的特征。

我们常用的属性和方法如下:

CBCentralManager

CBCentralManager对象,就是所谓的中心管理对象,是本地中心设备的CoreBluetooth面向对象的象征。可以通过CBManagerState来获取当前CBCentralManager对象的状态。如下代码所示

public enum CBManagerState : Int {
    case unknown = 0    //未知
    case resetting = 1  //复位
    case unsupported = 2 //该设备不支持蓝牙
    case unauthorized = 3//该设备无权限使用蓝牙
    case poweredOff = 4  //蓝牙关闭
    case poweredOn = 5   //蓝牙打开
}
复制代码

初始化

CBCentralManager的初始化方法有两种

public convenience init(delegate: CBCentralManagerDelegate?, queue: DispatchQueue?)

@available(iOS 7.0, )
public init(delegate: CBCentralManagerDelegate?, queue: DispatchQueue?, options: [String : Any]? = nil)
复制代码

delegate:设置代理
queue:指明在哪个队列处理事件,为nil时表示在主线程处理
options:这个字典有俩个官方的key
CBCentralManagerOptionShowPowerAlertKey:提示蓝牙开关未打开时会弹出警告框
CBCentralManagerOptionRestoreIdentifierKey:系统使用此UID来识别特定的
CentralManager。 因此,为了继续执行应用程序,UID必须保持不变,以便CentralManager成功恢复。

常用的CBCentralManagerDelegate,CBPeripheralDelegate的代理方法比较多,以下只列取部分

连接状态的更新,可以通过此代理方法可以获取当前设备蓝牙是否可用

扫描二维码关注公众号,回复: 13851316 查看本文章
func centralManagerDidUpdateState(_ central: CBCentralManager)
复制代码

扫描发现设备

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber)
复制代码

注意⚠️:在扫描发现设备中,iOS端不能像安卓一样直接获取蓝牙的Mac地址,iOS端的蓝牙Mac地址是存储在advertisementData中,需要做进一步转化,可通过如下方法转化

let _tempData = advertisementData["kCBAdvDataManufacturerData"]

let macAddress = "\(String(describing: _tempData))".substring(from: "<").substring(to: ">").replacingOccurrences(of: " ", with: "").uppercased().reversed(preserveFormat: false).substring(to: 12).reversed(preserveFormat: false)
复制代码

蓝牙设备已连接

func centralManager( _ central: CBCentralManager, didConnect peripheral: CBPeripheral)
复制代码

蓝牙设备连接失败,可以通过打印错误信息来排查失败原因

func centralManager( _ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?)
复制代码

蓝牙设备已经断开连接

func centralManager( _ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?)
复制代码

指令的发送,是使用CBPeripheral下的 func writeValue( _ data: Data, for characteristic: CBCharacteristic, type: CBCharacteristicWriteType)方法 其中CBCharacteristicWriteType有两个值分别为withResponse与withoutResponse,有些同学给蓝牙发送指令,但是蓝牙设备无响应,就是这个值弄错了,不清楚用哪个值的同学,可以和嵌软的同学确认下。

关于蓝牙数据的读取与解析在此就不多做阐述了,说到底只是数据包的解析,定义字段的读取等。

猜你喜欢

转载自juejin.im/post/7081641447702659085