+-
iOS之CoreBluetooth
首页 专栏 ios 文章详情
0

iOS之CoreBluetooth

善斋书屋 发布于 今天 01:30

思路

手机与设备间的通讯方式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)
    }
}
结束
ios
阅读 21 发布于 今天 01:30
收藏
分享
本作品系原创, 采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议
avatar
善斋书屋
1 声望
0 粉丝
关注作者
0 条评论
得票 时间
提交评论
avatar
善斋书屋
1 声望
0 粉丝
关注作者
宣传栏
目录

思路

手机与设备间的通讯方式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)
    }
}
结束