思路
手机与设备间的通讯方式CoreBluetooth是比较常见且通用的。在iOS开发中需明晰以下几点
- 蓝牙4.0最多可联机7个设备,iPhone6以上都是蓝牙4.0
- 两台iPhone并不直接通过蓝牙互相搜索配对
- 苹果设备不支持和其他非苹果设备连接蓝牙,当然,除了蓝牙耳机和车载蓝牙之外
- 蓝牙传输的字节顺序是小端
- CoreBluetooth的最大传输单元是20个字节
知识科普:
字节顺序只是对内置数据类型而言
例如对于一整型(int,int 是内置数据类型)数,比如 0x123456 大端模式: 高地址---------->低地址 0x56 | 0x34 | 0x12 小端模式: 高地址 ---------->低地址 0x12 | 0x34 | 0x56
流程
以中心设备为例分析整个流程
1.实例化中心设备管理者
cManager = CBCentralManager(delegate: self, queue: nil)
2.监测状态为PowOn,并搜索附近设备
func centralManagerDidUpdateState(_ central: CBCentralManager) { if central.state == .poweredOn { scanForServices() } else { print("\(central.state)") } }
3.发现外设,保存并展示
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { if let name = peripheral.name { if !list.contains(name) { list.append(name) dict[name] = peripheral table.reloadData() } } }
4.根据需要选择连接的外设
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // 连接设备 if let pheral = dict[list[indexPath.row]] { cManager?.connect(pheral, options: nil) } }
5.连接外设,失败/成功,成功则扫描外设服务
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) { print("连接外设失败") } func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { // 停止扫描 central.stopScan() print("连接外设成功") peripheral.delegate = self self.peripheral = peripheral // 扫描外设的服务 peripheral.discoverServices([CBUUID(string: "打印")]) }
6.回调中发现服务
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { var findService: CBService? for item in peripheral.services ?? [] { print(item.uuid) // 如果服务调用在service中 if item.uuid.isEqual(CBUUID(string: "打印")) { findService = item } } if let findService = findService { peripheral.discoverCharacteristics(nil, for: findService) } }
7.查询服务下面的特征,回调中返回 then发送打印数据
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { for item in service.characteristics ?? [] { if item.uuid.isEqual(CBUUID(string: "打印")) { // 读取成功回调didUpdateValueForCharacteristic self.characteristic = item // 接收一次(是读一次信息还是数据经常变实时接收视情况而定, 再决定使用哪个) peripheral.readValue(for: item) // 订阅、实时接收 peripheral.setNotifyValue(true, for: item) // 发送下行指令【发送一条】 guard let data = "硬件工程师给我的指令, 发送给蓝牙该指令, 蓝牙会给我返回一条数据".data(using: .utf8) else { return } self.peripheral?.writeValue(data, for: item, type: .withResponse) } // 当发现characteristic有descriptor,回调didDiscoverDescriptorsForCharacteristic peripheral.discoverDescriptors(for: item) } }
8.从外围设备读取数据
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { //characteristic.value就是蓝牙传递过来的值 print("\(String(describing: characteristic.value))") }
9.中心设备读取外设实时数据
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) { if characteristic.isNotifying { peripheral.readValue(for: characteristic) } else { print("notification stoped on \(characteristic)") self.cManager?.cancelPeripheralConnection(peripheral) } }
- 结束
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。