//
// 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?
}
网友评论