iOS蓝牙

由于公司项目需求,研究一下iOS的蓝牙(中心者模式)

一.概念名词

服务:蓝牙外围设备对外连接必定提供一个或者多个服务,服务下边包含多个特征.
CBService的属性有:peripheral外围设备,isPrimary服务类型,includedServices服务列表,characteristics特征列表.
特征:存在于服务的下边,一个服务包含多个特征,特征中有一个属性value,就是蓝牙传输的数据,特征是于外界的最小单位.
UUID:蓝牙设备的唯一标识.

二.蓝牙设备的连接步骤

  1. 创建CBCentralManager中心设备管理者
  2. 使用scanForPeripherals方法通过中心设备管理者扫描外围设备
  3. 使用connect方法连接外围设备
  4. 连接外围设备成功,设置外围设备delegate,开始扫描服务
  5. 通过discoverCharacteristics方法扫描服务特征
  6. 从外围设备读取数据
  7. 给外围设备发送数据

三.代码实现

  1. 创建CBCentralManager中心设备管理者,设置管理者代理,当CBCentralManager管理者被创建以后,就会调用centralManagerDidUpdateState方法.在该方法中可以检测蓝牙状态.
    // 中心设备管理者
    var manager : CBCentralManager!;

    // 在viewDidLoad中创建CBCentralManager,并设置代理
    override func viewDidLoad() {
        super.viewDidLoad()
        manager = CBCentralManager(delegate: self, queue: nil)
        manager.delegate = self;
    }
func centralManagerDidUpdateState(_ central: CBCentralManager) {
    switch central.state {
    case .unknown:
        print("未知蓝牙")
        break
    case .resetting:
        print("蓝牙连接暂时丢失")
        break
    case .unsupported:
        print("不支持蓝牙")
        break
    case .unauthorized:
        print("未授权")
        break
    case .poweredOff:
        print("未开启蓝牙")
        break
    case .poweredOn:
        print("蓝牙已开启")
        break
    default:
        break;
    }
}
  1. 使用scanForPeripherals方法通过中心设备管理者扫描外围设备.
// 开始扫描外围设备,这里可以传入指定服务.
// 如果扫描到设备会调用方法
// centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber)
manager.scanForPeripherals(withServices: nil, options: nil)
  1. 发现外围设备
    将扫描到的外围设备保存到一个外围设备数组peripheralArray中,用tableView展示peripheralArray中的内容,刷新tableView数据.
    // 发现外围设备
    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        print(peripheral.name ?? 0)
        // 这里peripheral有时候返回的是空
        
        // 将发现的设备添加到外围设备数组中
        if peripheral.name != nil {
            peripheralArray.append(peripheral)
        }
        tableView.reloadData()
    }
  1. 连接外围设备成功,设置外围设备delegate,开始扫描服务
    点击tableView中的cell,取出对应外围设备数组peripheralArray中的外围设备,开始连接外围设备.如果设备连接成功会调用方法centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral).如果连接失败则会调用方法centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?),设置外围设备的代理delegate,并且开始扫描服务.
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        peripheral = peripheralArray[indexPath.row] as! CBPeripheral
        
        // 这里可以做判断,满足我们的条件才连接
        if peripheral.name == "LF-000010" {
            // 停止扫描
            manager.stopScan()
            // 开始连接
            manager.connect(peripheral, options: nil)
        }
    }
    // 连接外围设备成功
    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        print("连接到了")
        central.stopScan()
        // 设置外设代理
        peripheral.delegate = self
        // 发现服务,如果传nil,就会发现所有的服务
        peripheral.discoverServices(nil)
    }
  1. 通过discoverCharacteristics方法扫描服务特征
    当扫描服务成功以后会调用方法peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?),在这里调用peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?)方法,扫描特征值.
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        // 外围设备有很多服务,服务中有很多特征.
        //发现服务
        for service in peripheral.services! {
            if service.uuid.uuidString == "49535343-FE7D-4AE5-8FA9-9FAFD205E455" {
                print("发现服务")
                // 扫描特征值
                peripheral.discoverCharacteristics(nil, for: service)
            }
        }
    }
    // 扫描到特征值
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        if error != nil {
            print("扫描特征错误")
            return
        }
        for characteristic in service.characteristics! {
            //发现特征
            print(characteristic)
            if characteristic.uuid.uuidString == "49535343-1E4D-4BD9-BA61-23C647249616" {
                // 监听特征
                peripheral.setNotifyValue(true, for: characteristic)
            }
            print(characteristic)
        }
    }
  1. 接收到数据
    因为已经对特征进行了监听,如果往外围设备的特征里写数据,就会调用peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?)方法
    // 接收到数据
    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
        print(characteristic.value)
    }
  1. 给外围设备发送数据
//第一个参数是已连接的蓝牙设备 ;第二个参数是要写入到哪个特征; 第三个参数是通过此响应记录是否成功写入
peripheral.writeValue(<#T##data: Data##Data#>, for: <#T##CBCharacteristic#>, type: <#T##CBCharacteristicWriteType#>)

中间有些问题待处理,后续更新...

你可能感兴趣的:(iOS蓝牙)