美文网首页iOS BLEMangoJ-说-Swift程序员
iOS开发:使用swfit进行蓝牙开发详解

iOS开发:使用swfit进行蓝牙开发详解

作者: MangoJ | 来源:发表于2016-12-12 19:39 被阅读231次

    最近我一直在做蓝牙开发的应用,大家也可能意识到,当下蓝牙开发可谓是越来越火,不论是智能穿戴的兴起还是蓝牙家具,车联网蓝牙等等,很多同学也会接触到蓝牙的项目,我从事蓝牙开发也有一段时间了,经手了两个项目。废话不多说了,先向大家简单的介绍有关蓝牙开发的知识。蓝牙低能耗(BLE),以下介绍的都是围绕iOS的框架展开的。

    蓝牙开发分为中心者模式和管理者模式:1.常用的(其实99.99%)就是使用中心者模式作为开发,就是我们手机作为主机,连接蓝牙外设;2.管理者模式,这个基本用到的比较少,我们手机自己作为外设,自己创建服务和特征,然后有其他的设备连接我们的手机。

    在做蓝牙开发之前,最好先了解一些概念:
    服务(services):蓝牙外设对外广播的必定会有一个服务,可能也有多个,服务下面包含着一些特征,服务可以理解成一个模块的窗口;
    特征(characteristic):存在于服务下面的,一个服务下面也可以存在多个特征,特征可以理解成具体实现功能的窗口,一般特征都会有value,也就是特征值,特征是与外界交互的最小单位;
    UUID:可以理解成蓝牙上的唯一标识符(硬件上肯定不是这个意思,但是这样理解便于我们开发),为了区分不同的服务和特征,或者给服务和特征取名字,我们就用UUID来代表服务和特征。

    蓝牙连接可以大致分为以下几个步骤
    1.建立一个Central Manager实例进行蓝牙管理
    2.搜索外围设备
    3.连接外围设备
    4.获得外围设备的服务
    5.获得服务的特征
    6.从外围设备读数据
    7.给外围设备发送数据
    其他:提醒

    首先是导入框架import CoreBluetooth
    必须遵守2个协议
        <CBCentralManagerDelegate, CBPeripheralDelegate>
    
    定义中心管理者
        fileprivate var centralManager :CBCentralManager!
    
    定义外设
         fileprivate var curretPeripheral :CBPeripheral!
    
    1.创建中心设备进行蓝牙管理并设置代理:
    func setupBluretooth(){
         centralManager = CBCentralManager(delegate: self, queue: nil)
      }
    
    //只要中心管理者初始化 就会触发此代理方法 判断手机蓝牙状态
    
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
    
        switch central.state {
    
        case.poweredOff:
            print("蓝牙以关闭")
        case .unsupported:
            print("不支持蓝牙")
        case .unknown:
            print("蓝牙状态未知")
        case .resetting:
            print("重置")
        case .poweredOn:
            print("蓝牙以打开")
            //利用中心设备扫描外部设备:
            //第一个参数那里表示扫描带有相关服务的外部设备,例如填写@[[CBUUIDUUIDWithString:@"需要连接的外部设备的服务的UUID"]],即表示带有需要连接的外部设备的服务的UUID的外部设备,nil表示扫描全部设备;
            central.scanForPeripherals(withServices: nil, options: nil)
            // 搜索成功之后,会调用我们找到外设的代理方法 
            // func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber)
        default:
            print("此设备不支持BLE或未打开蓝牙功能,无法作为外围设备.")
        }
      
    }
    
    2.搜索外围设备(发现设备),一旦扫描到外部设备,就会进入下列协议中的
    /// - parameter central:           中心管理者
    /// - parameter peripheral:        外设
    /// - parameter advertisementData: 外设携带的数据
    /// - parameter RSSI:              外设发出的蓝牙信号强度
    
    func centralManager(_ central: CBCentralManager,didDiscover peripheral: CBPeripheral, advertisementData: [String : Any],rssi RSSI: NSNumber)  {
         
    //在这个方法里,我们可以根据我们获取到的硬件的某些条件进行筛选,然后连接我们需要连接的外部设备
        print("扫描到的蓝牙设备:\(peripheral)")
        //这里我是将扫描到的设备显示在tableView里
        //通过点击tableView的cell选择连接到蓝牙设备
        //peripherals 是存放 蓝牙设备的数组
        
        peripherals.append(peripheral)
        tableView.reloadData()
    
    }
    
    3.连接外围设备
    // 中心管理者连接  外设成功
    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
         print("连接成功")
        //停止扫描
         centralManager.stopScan()
        // 外围设备设置代理
        peripheral.delegate = self
        
        //我们在连接成功的方法中开始扫描外部设备的服务
       
        peripheral.discoverServices(nil)
    
    }
    
     //连接失败
    func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
        print("连接失败")
    }
    //断开连接
    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
        print("断开连接")
    }
    
    4.获得外围设备的服务
     //接着就会跳入发现服务的代理方法中去:
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
     print("发现服务:\(peripheral.services)")
    
        for service in peripheral.services! {
            //我们在这个方法里面开始扫描服务中的特征:
    
           //serviceUUID 服务UUID(已知)
           //kCharacteristicUUID 特证UUID(已知)
    
    
            let serviceuuid:CBUUID? =
                CBUUID.init(string: "\(serviceUUID)")
            let characteristicUUID:CBUUID? =
                CBUUID.init(string: "\(kCharacteristicUUID)")
    
            if service.uuid == serviceuuid {
    peripheral.discoverCharacteristics([characteristicUUID!], for: service)
            }
    
        }
    }
    
    5.获得服务的特征
    //当我们扫描到特征的时候,就会跳入发现特征的协议方法里去
    //(这个是比较重要的方法,你在这里可以通过事先知道UUID找到你需要的特征,订阅特征,或者这里写入数据给特征也可以)
     func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
    if (error != nil) {
            print("error Discovered characteristics for\(service.uuid)---\(error?.localizedDescription)")
        }
        
        let serviceuuid:CBUUID? =
            CBUUID.init(string: "\(serviceUUID)")
        let characteristicUUID:CBUUID? =
            CBUUID.init(string: "\(kCharacteristicUUID)")
    
        if service.uuid == serviceuuid {
            
            for characteristic in service.characteristics! {
                print(service.uuid)
                print(service.uuid.description)
                   print("\(service.uuid)-----\(characteristic.uuid)")
                if characteristic.uuid == characteristicUUID {
                    
                    
                    //获取Characteristic的值,读数据:
                    peripheral.readValue(for: characteristic)
                    
                    //1.给外围设备发送数据(也就是写入数据到蓝牙)
                    //2.这个方法你可以放在button的响应里面,也可以在找到特征的时候就写入,具体看你业务需求怎么用啦
                    //3.第一个参数是已连接的蓝牙设备 ;第二个参数是要写入到哪个特征; 第三个参数是通过此响应记录是否成功写入
                    //4. 需要注意的是特征的属性是否支持写数据
               //peripheral.writeValue(要写入的Data, for: characteristic, type: CBCharacteristicWriteType.withResponse)
    
                }
    
            }
    
        }
        
        //这就读取了特征包含的相关信息,只要读取就会进入下面方法:
    
    }
    
    6.从外围设备读数据
    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
    
        if (error != nil) {
            print("更新特征值时发生错误,错误信息:\(error?.localizedDescription)")
            return
        }
     
        if characteristic == @"你要的特征的UUID或者是你已经找到的特征" {
    //characteristic.value就是你要的数据
        }
    
    }
    
    7.给外围设备发送数据(也就是写入数据到蓝牙)
    //这个方法你可以放在button的响应里面,也可以在找到特征的时候就写入,具体看你业务需求怎么用啦
     peripheral.writeValue(characteristic.value!, for: characteristic, type:.withResponse)
        // 最后的type类型有两个,分别是CBCharacteristicWriteWithResponse和CBCharacteristicWriteWithoutResponse;
        // 选择第一个,每往硬件写入一次数据都会进入下边的方法
    
    这个方法会告诉我们这次的写入是否成功,但是如果我们不用考虑往硬件写入的数据成功与否的话,选择第二个类型就ok。
    func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
        
    }
    

    蓝牙开发的基本方法就这么多,有写的不好不对的地方欢迎指正,分享一是为了提升自己和二是希望能对需要的朋友有所帮助!

    相关文章

      网友评论

        本文标题:iOS开发:使用swfit进行蓝牙开发详解

        本文链接:https://www.haomeiwen.com/subject/wywmmttx.html