关于BLE开发(swift)

来源:互联网 发布:linux清空文本内容 编辑:程序博客网 时间:2024/05/20 07:14

随着智能硬件的发展,出现了很多智能硬件APP,比如配合运动手环的计步APP、配合体重秤的APP等。最近简单研究了一下
1.BLE
最新的蓝牙4.0以其低功耗著称,所以一般也叫BLE(Bluetooth Low Energy)。iOS 有两个框架支持蓝牙与外设连接。一个是 ExternalAccessory,从ios3.0就开始支持,也是在iphone4s出来之前用的比较多的一种模式,但是它有个不好的地方,External Accessory需要拿到苹果公司的MFI认证。另一个框架则是本文要介绍的CoreBluetooth,在iphone4s开始支持,专门用于与BLE设备通讯(因为它的API都是基于BLE的)。这个不需要MFI,并且现在很多蓝牙设备都支持4.0,所以也是在IOS比较推荐的一种开发方法。蓝牙4.0协议从iPhone 4s 以上开始支持, iPad 3.0以上 iPad Mini 及以上版本支持.
Core Bluetooth framework可以让你的iOS和Mac apps与Bluetooth Low Energy 设备(简写BLE)交流。这些设备包括心率监测器,数字体温计,等等。Core Bluetooth framework是一个对Bluetooth4.0 specification的抽象,并定义了一系列容易使用的协议来和BLE设备通信。

2.api参考
https://developer.apple.com/reference/corebluetooth
CBPeripheral 蓝牙外设,比如蓝牙手环、蓝牙心跳监视器、蓝牙打印机。
CBCentralManager 蓝牙外设管理中心,与手机的蓝牙硬件模板关联,可以获取到手机中蓝牙模块的一些状态等,但是管理的就是蓝牙外设。
CBService 蓝牙外设的服务,每一个蓝牙外设都有0个或者多个服务。而每一个蓝牙服务又可能包含0个或者多个蓝牙服务,也可能包含0个或者多个蓝牙特性。
CBCharacteristic 每一个蓝牙特性中都包含有一些数据或者信息。
下面看demo,系统的方法如果直接拿出来用,感觉过于繁琐,所以我这里封装了一个工具类:

import CoreBluetoothprotocol BLEToolDelegate : NSObjectProtocol{    //发现设备    func didDiscoverPeripheral(_ peripheral: CBPeripheral!)    //读取数据    func readData(data:Data!)}class BLETool: NSObject,CBCentralManagerDelegate,CBPeripheralDelegate {    //添加属性    private var centralManager: CBCentralManager!    private var peripheral: CBPeripheral!    private var writeCharacteristic: CBCharacteristic!    //保存收到的蓝牙设备    var services:Array<CBPeripheral> = Array<CBPeripheral>()    weak var delegate : BLEToolDelegate!    override init() {        super.init()        self.centralManager = CBCentralManager.init(delegate: self, queue: nil)    }    class func shared() -> BLETool{        struct Static {            static let instance: BLETool = BLETool()        }        return Static.instance    }    /** 停止扫描 **/    func stopScan() {        self.centralManager.stopScan()    }    //我们需要实现CBCentralManagerDelegate协议来允许代理监测发现,连接,检索设备.    //CBCentralManager对象初始化完毕后自动调用此方法;    func centralManagerDidUpdateState(_ central: CBCentralManager) {        switch central.state {        case .poweredOff:            print("蓝牙已关闭")            break        case .poweredOn:            print("蓝牙已打开,请扫描外设")            centralManager.scanForPeripherals(withServices: nil, options:[CBCentralManagerScanOptionAllowDuplicatesKey: false])            break        case .resetting:            print("正在重置状态")            break        case .unauthorized:            print("无权使用蓝牙低功耗")            break        case .unknown:            print("未知设备")            break        case .unsupported:            print("此设备不支持BLE")            break        }    }    //这个方法在搜索的过程中,每发现一个peripheral(外围设备)就调用此方法一次    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {        if !self.services.contains(peripheral) {            self.services.append(peripheral)            if self.delegate != nil {                self.delegate.didDiscoverPeripheral(peripheral)            }        }    }    //连接外设成功,开始发现服务    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {        //停止扫描外设        self.centralManager.stopScan()        self.peripheral = peripheral        self.peripheral.delegate = self        //发现某些服务,若参数为nil则发现所有服务.        self.peripheral.discoverServices(nil)    }    //连接外设失败    func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {        print("连接外设失败===\(String(describing: error))")    }    //成功断开链接后    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {        print("连接已断开")    }    //我们需要实现CBPeripheralDelegate协议来监测发现,搜索与远程设备service的交互.    //成功发现服务,请求周边去寻找它的服务所列出的特征,当每发现一个服务时,调用下面方法一次.    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {        if error != nil {            print("连接外设失败===\(String(describing: error))")            return        }        for service in peripheral.services! {            peripheral.discoverCharacteristics(nil, for: service)        }    }    //成功发现特征,对于每个服务的每个特征被发现时都调用此方法一次    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {        print("发现特征的服务:\(service.uuid.data)   ===  服务UUID:\(service.uuid)")        if error != nil {            print("发现错误的特征:\(String(describing: error?.localizedDescription))")            return        }        for characteristic in service.characteristics! {            //罗列出所有特性,看哪些是notify方式的,哪些是read方式的,哪些是可写入的。            switch characteristic.uuid.description {            case "FFE1":                //如果以通知的形式读取数据,则直接发到didUpdateValueForCharacteristic方法处理数据。                self.peripheral.setNotifyValue(true, for: characteristic)                break            case "2A37":                //通知关闭,read方式接受数据。则先发送到didUpdateNotificationStateForCharacteristic方法,再通过readValueForCharacteristic发到didUpdateValueForCharacteristic方法处理数据。                self.peripheral.readValue(for: characteristic)                break            case "2A38":                self.peripheral.readValue(for: characteristic)                break            case "Battery Level":                self.peripheral.setNotifyValue(true, for: characteristic)                break            case "Manufacturer Name String":                self.peripheral.readValue(for: characteristic)                break            case "AF0BADB1-5B99-43CD-917A-A77BC549E3CC":                self.writeCharacteristic = characteristic                self.peripheral.writeValue("特征UUID:AF0BADB1-5B99-43CD-917A-A77BC549E3CC".data(using: .utf8)!, for: characteristic, type: .withoutResponse)                break            case "6E400002-B5A3-F393-E0A9-E50E24DCCA9E":                self.peripheral.readValue(for: characteristic)                break            default:                break            }        }    }    //获取外设发来的数据,不论是read和notify,获取数据都是从这个方法中读取。    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {        if error != nil {            print("更新数据失败\(String(describing: error?.localizedDescription))")            return        }        let data = characteristic.value        print("返回的数据是:\(data!)")        if self.delegate != nil {            self.delegate.readData(data: data)        }    }    //用于检测中心向外设写数据是否成功    func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {        if error != nil {            print("发送数据失败!error信息:\(String(describing: error))")        }    }    /** 写入数据 **/    func writeValue(data: NSData!){        self.peripheral.writeValue(data as Data, for: self.writeCharacteristic, type: CBCharacteristicWriteType.withoutResponse)        print("手机向蓝牙发送的数据为:\(data)")    }    /** 连接设备 **/    func connectPeripheral(_ peripheral: CBPeripheral){        self.centralManager.connect(peripheral, options: nil);    }    /** 主动断开设备 **/    func cancelPeripheralConnection() {        if self.peripheral != nil {            self.centralManager.cancelPeripheralConnection(self.peripheral)        }    }

当然这是我初步研究,对这个框架了解的还不够透彻,写的不足之处还请大家见谅!为大家推荐一个github上评分相对较高的三方库,他也是基于CoreBluetooth的封装—https://github.com/coolnameismy/BabyBluetooth

原创粉丝点击