也是醉了,CB这个API到现在也没有Swift的文档。最新的文档还是3年前还是4年前的OC版的,被雷的外焦里嫩的。自己一点一点写成Swift还各种报错,最坑的是这些错误压根找不到解决方案。索性自己做个个人专用的蓝牙通信库,顺便梳理下这一块。这篇博文讲中心模式

 
//----------------------------------------------------------------------------------
//                                               基本
//----------------------------------------------------------------------------------

首先设置代理类

class CentralManagerPro: NSObject, CBCentralManagerDelegate

 

创建中心设备管理器

centralManager = CBCentralManager(delegate: self, queue: nil, options: nil)

delegate就是处理中心设备管理器相关事件的,继承CBCentralManagerDelegate的一系列方法全部写在里面。这里就是self,也就是这个管理器所在的类

特别注意,这个中心设备管理器不要重复生成。不然会报错,而且上网搜也没有解决方法。我就为此花了老半天。

 

开始扫描

 

if centralManager.state == .poweredOn {

            centralManager.scanForPeripherals(withServices: nil, options: nil)

            return true

        }else {

            return false

 

        }

虽然网上没有任何资料这么写,但是目前新版本里如果不判断中心设备是否开启就直接进行活动会报错。下面所有函数相同

这里的withServices是周边设备内部需要有的服务,如果不指定那所有搜索到的周边设备都会反馈


扫描到以后为了省电,停止扫描

 

centralManager.stopScan()


连接扫描到的设备

 

if peripheral != nil {

            centralManager.connect(peripheral, options: nil)

            return true

        }else {

            return false

 

        }

连接成功呼出func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral)

连接失败呼出func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) 

 

搜索服务和特征 

搜索连接上的周边设备有的服务

if peripheral != nil {

            peripheral.discoverServices(serviceUUIDs)

        }

这样的好处是防止搜索以及实效的周边设备,避免程序崩溃

搜索到以后会自动呼出func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?)

 

搜索到自己要的服务以后,进一步搜索自己要的特性

 

 peripheral.discoverCharacteristics(characteristicUUIDs, for: service)

搜索完成后会呼出 func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error

 

搜索到特性后,获取特性的值

peripheral.readValue(for: char)

获得了值后会自动呼出如下函数 func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?)

改写特性的值

peripheral.writeValue(data, for: char, type: CBCharacteristicWriteType.withoutResponse)

CBCharacteristicWriteType.withoutResponse这样设置后自己会运行

服务的特性的值被改写后会自动呼出如下函数

(CBCharacteristicWriteType.withoutResponse这样设置后)

//didWriteValueFor

    func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {

        if let error = error {

            print("Write失敗...error: \(error)")

            return

        }

        print("Write成功!")

 

    }

获取特性值的更新通知

peripheral.setNotifyValue(true, for: char)

不获取特性值的更新通知

peripheral.setNotifyValue(false, for: char)

状态更新后会自动呼出如下函数func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) 

 

//----------------------------------------------------------------------------------
//                                       回调函数(继承协议)
//----------------------------------------------------------------------------------

//-------------------------------------------------------------------

//                            CBCentralManagerDelegate

//-------------------------------------------------------------------

发现了周边设备的话,回自动呼出下面这个函数

///didDiscover

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

        let state = "discoverd peripheral: \(peripheral.services)\n"

        print(state)

        self.peripheral = peripheral

    }

 

连接结果

//didConnect

    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {

        let state = "central: connected!\n"

        print(state)

    }

    //didFailToConnect

    func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {

        let state = "central: failed to connected\n"

        print(state)

 

    }

 

//-------------------------------------------------------------------

//                            CBPeripheralDelegate 

//-------------------------------------------------------------------

搜索服务完毕后会自动呼出如下函数

//didDiscoverServices

    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {

        guard let services = peripheral.services else{

            print("error")

            return

        }

        print("\(services.count)個のサービスを発見。\(services)")

    }

 

搜索完指定服务的特性后会呼出如下函数

//didDiscoverCharacteristicsFor

    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {

        if let error = error {

            print("error: \(error)")

            return

        }

        

        let characteristics = service.characteristics

        print("Found \(characteristics?.count ?? 0) characteristics! : \(characteristics)")

 

    }

 

获取指定的特性的值时会呼出如下函数

//didUpdateValueFor

    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {

        if let error = error {

            print("Failed... error: \(error)")

            return

        }

        print("Succeeded! service uuid: \(characteristic.service.uuid), characteristic uuid: \(characteristic.uuid), value: \(characteristic.value)")

 

    }

服务的特性的值被改写后会自动呼出如下函数

(CBCharacteristicWriteType.withoutResponse这样设置后)

//didWriteValueFor

    func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {

        if let error = error {

            print("Write失敗...error: \(error)")

            return

        }

        print("Write成功!")

 

 

    }

状态更新后会自动呼出如下函数

//didUpdateNotificationStateFor

    func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {

        if let error = error {

            print("Notify状態更新失敗...error: \(error)")

        } else {

            print("Notify状態更新成功! isNotifying: \(characteristic.isNotifying)")

        }

    }