iOS蓝牙功能介绍

文章目录

  • 一、蓝牙BLE
  • 二、蓝牙设备间是怎么连接交互的?
  • 三、蓝牙连接
    • 1. 初始化蓝牙中心
    • 2. 扫描蓝牙
    • 3. 停止扫描
    • 4. 连接蓝牙
    • 5. 获取连接过的设备
    • 6. 断开蓝牙连接
    • 7. 蓝牙中心代理
      • 7.1 蓝牙状态
      • 7.2 发现蓝牙设备
      • 7.3 蓝牙连接
      • 7.4 蓝牙连接失败
      • 7.5 蓝牙断开连接
      • 7.6 蓝牙恢复连接
    • 8. 蓝牙设备服务
      • 8.1 读取蓝牙 RSSI
      • 8.2 发现蓝牙服务
      • 8.3 订阅蓝牙特征
      • 8.4 蓝牙订阅成功
      • 8.5 蓝牙写数据回调
      • 8.6 蓝牙读数据
    • 9. 蓝牙写数据
    • 10. 蓝牙读数据

一、蓝牙BLE

BLE是蓝牙4.0(Bluetooth low energy)的简称,特点就是低耗电。

二、蓝牙设备间是怎么连接交互的?

只要是集成了蓝牙BLE模块的设备,都可以通过蓝牙协议栈(GATT、ATT、L2CAP)进行交互。iphone和mac都集成了BLE,我们可以通过框架与底层的蓝牙协议栈进行交互。
举例:当iPhone作为中心设备时,通过CBCentralManager来管理 Remote Peripheral(CBPeripheral、CBCharacteristic、CBService).
当iPhone作为外设时,通过CBPeripheralManager、可变的CBMutableService、CBMutableCharacteristic提供服务。

中心设备和外设的区别与规范
中心设备Central是发起蓝牙连接的设备,并对外设Peripheral进行管理。
中心设备的规范需要提供三个功能:
1.搜索连接外设;
2.与外设提供的数据交互;
3.订阅一个当数据发生变化就会发出通知的特征Characteristic。
外设Peripheral通过Radio(无线电广播设备)广播数据包,提供数据的一方。外设的规范也需要提供三个功能:
1.发布、广播服务Service;
2.响应对特征的读写请求;
3.响应对特征的订阅请求。

三、蓝牙连接

1. 初始化蓝牙中心

CBCentralManager 是中心设备管理者,并设置代理

let dic = [CBCentralManagerOptionRestoreIdentifierKey: kRestoreIdentifierKey]
centralManager = CBCentralManager.init(delegate: self, queue: .main, options: nil)

options:
CBCentralManagerOptionShowPowerAlertKey 用于当中心管理类被初始化时若此时蓝牙系统为关闭状态,是否向用户显示警告对话框。该字段对应的是NSNumber类型的对象,默认值为NO
CBCentralManagerOptionRestoreIdentifierKey 中心管理器的唯一标识符,系统根据这个标识识别特定的中心管理器,为了继续执行应用程序,标识符必须保持不变,才能还原中心管理类

判断蓝牙状况,能获得当前设备是否能作为 central

// MARK: - CBCentralManagerDelegate
extension DKCBCenterManager: CBCentralManagerDelegate {
    // 蓝牙状态
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        switch central.state {
        case .poweredOn:
           
            scanBluetooth()
        case .poweredOff:
            delegate?.bleDidUpdateState(central)
        default:
            break
        }
    }
}
  1. 状态未知
    CBCentralManagerStateUnknown = 0,
  2. 连接断开 即将重置
    CBCentralManagerStateResetting,
  3. 该平台不支持蓝牙
    CBCentralManagerStateUnsupported,
  4. 未授权蓝牙使用 hovertree.com
    CBCentralManagerStateUnauthorized,
  5. 蓝牙关闭
    CBCentralManagerStatePoweredOff,
  6. 蓝牙正常开启
    CBCentralManagerStatePoweredOn,

2. 扫描蓝牙

 let options: [String: Any] = [CBCentralManagerScanOptionAllowDuplicatesKey: NSNumber(value: false)]
centralManager.scanForPeripherals(withServices: nil, options: options)
  • UUID
    表示外设的服务标识,当serviceUUIDs参数为nil时,将返回所有发现的外设(苹果不推荐此种做法);当填写改服务标识时,系统将返回对应该服务标识的外设

  • options
    CBCentralManagerScanOptionAllowDuplicatesKey 是否允许重复扫描设备,默认为NO,官方建议此值为NO,当为YES时,可能对电池寿命产生影响,建议在必要时才使用
    CBCentralManagerScanOptionSolicitedServiceUUIDsKey 想要扫描的服务的UUID,对应一个NSArray数值

3. 停止扫描

centralManager?.stopScan()

4. 连接蓝牙

let options = [CBConnectPeripheralOptionNotifyOnNotificationKey: true]
centralManager?.connect(peripheral, options: nil)

CBConnectPeripheralOptionNotifyOnConnectionKey 应用程序被挂起时,成功连接到外设,是否向用户显示警告对话框,对应NSNumber对象,默认值为NO
CBConnectPeripheralOptionNotifyOnDisconnectionKey 应用程序被挂起时,与外设断开连接,是否向用户显示警告对话框,对应NSNumber对象,默认值为NO
CBConnectPeripheralOptionNotifyOnNotificationKey 应用程序被挂起时,只要接收到给定peripheral的通知,是否就弹框显示

5. 获取连接过的设备

// 重新获取当前连接着的设备列表
        var peripheralArray = centralManager.retrieveConnectedPeripherals(withServices: [peripheraUUID])
// 重新获取已发现的设备列表
        guard let bleUUID = bleUUID else { return }
        peripheralArray = centralManager.retrievePeripherals(withIdentifiers: [bleUUID])

6. 断开蓝牙连接

centralManager?.cancelPeripheralConnection(peripheral)

7. 蓝牙中心代理

CBCentralManagerDelegate

7.1 蓝牙状态

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        switch central.state {
        case .poweredOn:
            scanBluetooth()
        case .poweredOff:
            delegate?.bleDidUpdateState(central)
        default:
            break
        }
    }

7.2 发现蓝牙设备

    func centralManager(_ central: CBCentralManager,
                        didDiscover peripheral: CBPeripheral,
                        advertisementData: [String: Any],
                        rssi RSSI: NSNumber) {
    }

7.3 蓝牙连接

    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        stopScanBluetooth()
        // 连接蓝牙设备的代理
        peripheral.delegate = self
        self.peripheral = peripheral
    }

7.4 蓝牙连接失败

    func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
        DKLog("*************** 蓝牙连接失败")
        delegate?.bleDidFailToConnectPeripheral(peripheral, error: error)
    }

7.5 蓝牙断开连接

    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
        DKLog("*************** 断开蓝牙连接")
        delegate?.bleDidDisconnectPeripheral(peripheral, error: error)
    }

7.6 蓝牙恢复连接

func centralManager(_ central: CBCentralManager, willRestoreState dict: [String: Any]) {
        let arr = dict[CBCentralManagerRestoredStatePeripheralsKey]
        guard let peripheralArr = arr as? [CBPeripheral] else {
            return
        }
        let meek = peripheralArr[0]
        DKLog("*************** 蓝牙恢复连接 \(meek)")
//        self.connectPeripheral(meek, delegate: self)
}

8. 蓝牙设备服务

CBPeripheralDelegate

8.1 读取蓝牙 RSSI

    func peripheral(_ peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: Error?) {
        delegate?.bleDidReadRSSI(RSSI)
    }

8.2 发现蓝牙服务

    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
//        DKLog("*************** 发现蓝牙服务 \(peripheral.services)")
        peripheral.services?.forEach({ service in
            peripheral.discoverCharacteristics(nil, for: service)
        })
    }

8.3 订阅蓝牙特征

    func peripheral(_ peripheral: CBPeripheral,
                    didDiscoverCharacteristicsFor service: CBService,
                    error: Error?) {
//        DKLog("*************** 订阅蓝牙特征 \(service.characteristics)")
        if service.uuid.uuidString == configuration?.serviceUUIDString.uppercased() {
            characteristic_serve = service
            service.characteristics?.forEach({ characteristic in
                if characteristic.uuid.uuidString == configuration?.writeCharacteristicUUIDString.uppercased() {
                    characteristic_write = characteristic
                }
                if characteristic.uuid.uuidString == configuration?.readCharacteristicUUIDString {
                    characteristic_read = characteristic
                    peripheral.setNotifyValue(true, for: characteristic)
                }
            })
        }
        delegate?.bleDidDiscoverCharacteristicsForService(peripheral, error: error)
    }

8.4 蓝牙订阅成功

    func peripheral(_ peripheral: CBPeripheral,
                    didUpdateNotificationStateFor characteristic: CBCharacteristic,
                    error: Error?) {
        DKLog("*************** 订阅蓝牙通知 成功")
        delegate?.bleDidUpdateNotificationStateForCharacteristic(characteristic, error: error)
    }

8.5 蓝牙写数据回调

    func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
        DKLog("*************** didWriteValueForCharacteristic")
        DKLog(error)
        DKLog(characteristic)
    }

8.6 蓝牙读数据

    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
        delegate?.bleDidUpdateValue(characteristic, error: error)
    }

9. 蓝牙写数据

peripheral.writeValue(wdata, for: characteristic_write, type: .withoutResponse)

10. 蓝牙读数据

    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
        delegate?.bleDidUpdateValue(characteristic, error: error)
    }
}

你可能感兴趣的:(#,蓝牙开发,ios)