美文网首页
ios app作为蓝牙中心

ios app作为蓝牙中心

作者: liang1030 | 来源:发表于2019-12-19 09:54 被阅读0次
//
//  BLECenterManager.swift
//  remoteControl_ios
//
//  Created by liang on 2019/1/17.
//  Copyright © 2019 liang. All rights reserved.
//

import UIKit
import CoreBluetooth

//可以使用命令生成128位的UUID
// liangdeMac-mini:~ liang$ uuidgen
// AC586E87-17F8-42D0-818D-E6B0ECA954C0

private let Service_UUID: String = ""
private let Characteristic_UUID: String = ""

class BLECenterManager: NSObject {
    
    private var centralManager: CBCentralManager?
    private var currentPeripheral: CBPeripheral?
    private var characteristic: CBCharacteristic?
    private(set) var BLEState:CBManagerState?
    private(set) var devicesArr:NSMutableArray = NSMutableArray.init(capacity: 0)
    private var peripheralsArr:NSMutableArray = NSMutableArray.init(capacity: 0)
    
    var connectDeviceName:String = ""
    
    //蓝牙状态变更回调
    typealias BLEStateBlock = () -> ()
    var staseCallback: BLEStateBlock?
    //扫描到蓝牙回调
    typealias scanDevicesBlock = () -> ()
    var scanDevicesCallback: scanDevicesBlock?
    //蓝牙连接成功回调
    typealias connectedDevicesBlock = () -> ()
    var connectedDevicesCallback: connectedDevicesBlock?
    //蓝牙断开连接回调
    typealias disConnectedDevicesBlock = () -> ()
    var disConnectedDevicesCallback: disConnectedDevicesBlock?
    
    //接收到心跳包回调
    typealias recieveHeartbeatBlock = (_ dataStr:String) -> ()
    var recieveHeartbeatCallback: recieveHeartbeatBlock?
    
    //单例
    static let shared = BLECenterManager()
    
    private override init() {
        super.init()
        
        centralManager = CBCentralManager.init(delegate: self, queue: .main)
    }

}

extension BLECenterManager: CBCentralManagerDelegate, CBPeripheralDelegate {
    
    // 判断手机蓝牙状态
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        BLEState = central.state
        if staseCallback != nil {
            staseCallback!()
        }
        
        switch central.state {
        case .unknown:
            print("未知的")
        case .resetting:
            print("重置中")
        case .unsupported:
            print("不支持")
        case .unauthorized:
            print("未验证")
        case .poweredOff:
            print("未启动")
        case .poweredOn:
            print("可用")
        }
    }
    
    func startScanDevices(isRescan:Bool) {
        if isRescan {
            removeScanDevices()
        }
        centralManager?.scanForPeripherals(withServices: [CBUUID.init(string: Service_UUID)], options: nil)
    }
    
    func removeScanDevices() {
        devicesArr.removeAllObjects()
        peripheralsArr.removeAllObjects()
    }
    
    func stopScanDevives() {
        centralManager?.stopScan()
    }
    
    func connectDevice(peripheral: CBPeripheral) {
        disconnectDevice()
        
        self.currentPeripheral = peripheral
        centralManager?.connect(peripheral, options: nil)
    }
    
    func disconnectDevice() {
        if let per = currentPeripheral {
            centralManager?.cancelPeripheralConnection(per)
        }
    }
    
    func writeValue(dataStr:String) {
        let data = dataStr.data(using: .utf8)!
        self.currentPeripheral?.writeValue(data, for: characteristic!, type: .withResponse)
    }
    
    /** 发现符合要求的外设 */
    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        if let name = advertisementData["kCBAdvDataLocalName"] as? String {
            if !peripheralsArr.contains(peripheral) {
                let device:BLEDeviceModel = BLEDeviceModel()
                device.deviceName = name
                device.blePeripheral = peripheral
                
                devicesArr.add(device)
                peripheralsArr.add(peripheral)
                
                if connectDeviceName.count>0 {
                    if device.deviceName == connectDeviceName {
                        connectDevice(peripheral: peripheral)
                    }
                }
            }
        }
        
        if scanDevicesCallback != nil {
            scanDevicesCallback!()
        }
    }
    
    /** 连接成功 */
    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        if connectedDevicesCallback != nil {
            connectedDevicesCallback!()
        }
        stopScanDevives()
        peripheral.delegate = self
        peripheral.discoverServices([CBUUID.init(string: Service_UUID)])
        print("连接成功")
    }
    
    func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
        print("连接失败")
    }
    
    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
        print("断开连接")
        if error == nil {
            //主动断开连接(cancelPeripheralConnection)不需要重连
            return
        }
        removeScanDevices()
        if disConnectedDevicesCallback != nil {
            disConnectedDevicesCallback!()
        }
        // 重新连接
        central.connect(peripheral, options: nil)
    }
    
    /** 发现服务 */
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        for service: CBService in peripheral.services! {
            print("外设中的服务有:\(service)")
        }
        //本例的外设中只有一个服务
        let service = peripheral.services?.last
        // 根据UUID寻找服务中的特征
        peripheral.discoverCharacteristics([CBUUID.init(string: Characteristic_UUID)], for: service!)
    }
    
    /** 发现特征 */
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        for characteristic: CBCharacteristic in service.characteristics! {
            print("外设中的特征有:\(characteristic)")
        }
        
        self.characteristic = service.characteristics?.last
        // 读取特征里的数据
        peripheral.readValue(for: self.characteristic!)
        // 订阅
        peripheral.setNotifyValue(true, for: self.characteristic!)
    }
    
    /** 订阅状态 */
    func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
        if let error = error {
            print("订阅失败: \(error)")
            return
        }
        if characteristic.isNotifying {
            print("订阅成功")
        } else {
            print("取消订阅")
        }
    }
    
    /** 接收到数据 */
    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
        if let data = characteristic.value {
            recieveCommandFormPeripheral(data: data)
        }
    }
    
    /** 写入数据 */
    func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
        if (error != nil) {
            print("写入数据失败")
        }else {
            print("写入数据成功")
        }
    }
    
    func recieveCommandFormPeripheral(data:Data) {
        let command:String = String.init(data: data, encoding: .utf8) ?? ""
        if recieveHeartbeatCallback != nil {
            recieveHeartbeatCallback!(command)
        }
    }
    
    //callBack
    func bleStateCallBackBlock(_ block: @escaping BLEStateBlock) {
        staseCallback = block
    }
    
    func scanDevicesCallBackBlock(_ block: @escaping scanDevicesBlock) {
        scanDevicesCallback = block
    }
    
    func connectedDevicesCallBackBlock(_ block: @escaping connectedDevicesBlock) {
        connectedDevicesCallback = block
    }
    
    func disConnectedDevicesCallBackBlock(_ block: @escaping disConnectedDevicesBlock) {
        disConnectedDevicesCallback = block
    }
    
    func recieveHeartbeatCallBackBlock(_ block: @escaping recieveHeartbeatBlock) {
        recieveHeartbeatCallback = block
    }
}


class BLEDeviceModel: NSObject {
    var deviceName:String = ""
    var blePeripheral: CBPeripheral?
}

相关文章

网友评论

      本文标题:ios app作为蓝牙中心

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