我正在尝试创建一个使用CoreBluetooth的蓝牙类,该类可以通过依赖注入从应用程序的所有视图中使用。如果蓝牙仅包含一个带有蓝牙代码的视图,则蓝牙本身可以很好地工作,但我很难在不同的视图控制器中调用蓝牙的功能,然后我决定通过创建一个包含所有蓝牙代码的类来使用依赖注入。然后,创建一个var类型的蓝牙类名称,并尝试以这种方式使用它,但是应用程序崩溃,因为收到nil。
这是我称为CommonBLE的通用类的代码:
import Foundation
import UIKit
import CoreBluetooth
class CommonBLE: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate {
// Variables del Bluetooth
var manager:CBCentralManager?
var mainPeripheral:CBPeripheral?
var mainCharacteristic:CBCharacteristic?
var valueBLE:String?
//Para el nuevo bluetooth
let BLEService = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
let BLECharacteristic = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
let BLEService_CBUUID = CBUUID(string: "6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
let BLECharacteristic_CBUUID = CBUUID(string: "6E400003-B5A3-F393-E0A9-E50E24DCCA9E")
func connect() {
manager?.connect(mainPeripheral!, options: nil)
}
func disconnect() {
manager?.cancelPeripheralConnection(mainPeripheral!)
}
func startBLE() {
manager? = CBCentralManager(delegate: self, queue: nil);
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
print(central.state)
//manager?.scanForPeripherals(withServices: [BLEService_CBUUID])
manager?.scanForPeripherals(withServices: nil)
print("Scanning")
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
print(peripheral.name!)
mainPeripheral = peripheral
mainPeripheral?.delegate = self
manager?.stopScan()
//manager?.connect(mainPeripheral!)
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
mainPeripheral?.discoverServices([BLEService_CBUUID])
print("Connected to " + peripheral.name!)
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
mainPeripheral = nil
print("Disconnected" + peripheral.name!)
}
// MARK: CBPeripheralDelegate Methods
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
for service in peripheral.services! {
print("Service found with UUID: " + service.uuid.uuidString)
//Es posible cambiar BLEService por un "String"
if (service.uuid.uuidString == BLEService) {
peripheral.discoverCharacteristics(nil, for: service)
}
else
{
print("Service not found")
}
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
//Es posible cambiar BLEService por un "String"
if (service.uuid.uuidString == BLEService) {
for characteristic in service.characteristics! {
if (characteristic.uuid.uuidString == BLECharacteristic) {
//we'll save the reference, we need it to write data
mainCharacteristic = characteristic
//Set Notify is useful to read incoming data async
peripheral.setNotifyValue(true, for: characteristic)
print("Found Bluno Data Characteristic")
}
else {
print("Characteristic not found")
}
}
}
else {
print("Service not found")
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if (characteristic.uuid.uuidString == "2A00") {
//value for device name recieved
let deviceName = characteristic.value
print(deviceName ?? "No Device Name")
} else if (characteristic.uuid.uuidString == "2A29") {
//value for manufacturer name recieved
let manufacturerName = characteristic.value
print(manufacturerName ?? "No Manufacturer Name")
} else if (characteristic.uuid.uuidString == "2A23") {
//value for system ID recieved
let systemID = characteristic.value
print(systemID ?? "No System ID")
} else if (characteristic.uuid.uuidString == BLECharacteristic) {
//data recieved
if(characteristic.value != nil) {
valueBLE = String(data: characteristic.value!, encoding: String.Encoding.utf8)!
}
else {
print("Error")
}
}
}
}
此外,我还在AppDelegate中包含了以下代码,以使用CommonBLE()压紧ViewController。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
if let viewController = window?.rootViewController as? ViewController {
viewController.modelController = CommonBLE()
}
return true
}
最后这是View Controller的代码,我想在其中使用CommonBLE类的Bluetooth功能。
import Foundation
import UIKit
import CoreBluetooth
class ViewController: UIViewController {
var modelController: CommonBLE!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
@IBAction func ConnectButton(_ sender: Any) {
modelController.connect()
}
@IBAction func DisconnectButton(_ sender: Any) {
modelController.disconnect()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
modelController.startBLE()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let editViewController = segue.destination as? BluetooothViewController {
editViewController.modelController = modelController
}
}
}
因此,当调用modelController.startBLE()函数时:
manager? = CBCentralManager(delegate: self, queue: nil);
然后我得到一个错误,因为它传递了nil并且无法连接。有人可以帮助我以正确的方式与视图控制器进行通信并使蓝牙在所有控制器中均可使用吗?
谢谢!