关于ios:iOS之CoreBluetooth

  • 思路

    手机与设施间的通信形式CoreBluetooth是比拟常见且通用的。在iOS开发中需清晰以下几点

    1. 蓝牙4.0最多可联机7个设施,iPhone6以上都是蓝牙4.0
    2. 两台iPhone并不间接通过蓝牙相互搜寻配对
    3. 苹果设施不反对和其余非苹果设施连贯蓝牙,当然,除了蓝牙耳机和车载蓝牙之外
    4. 蓝牙传输的字节程序是小端
    5. 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)
        }
    }
  • 完结

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理