从 2 个 UIViewController 上的 BLE 设备读取值
Read value from BLE device on 2 UIViewControllers
目前我的 MainViewController 可以连接到我的蓝牙模块并读取来自它的数据。
现在,我正在尝试从另一个视图控制器读取数据。
我的蓝牙管理器是单例的,所以它不会被多次实例化。为了读取和处理适当的 ViewController 中的数据,我正在考虑使用可选委托。当我到达 receivedMVC(data: String) 时它工作正常但在到达 receivedUVC(data: String)
时崩溃
我收到以下错误:
[BLE_Tests.MainViewController receivedUVCWithData:]: unrecognized
selector sent to instance 0x100d0a9d0 2017-06-22 16:25:58.634682-0700
BLE_Tests[9544:2692419] * Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[BLE_Tests.MainViewController
**receivedUVCWithData:]: unrecognized selector sent to instance
0x100d0a9d0'
如果我将 receivedUVC(data:String) 添加到我的 MainViewController,它不会崩溃但不会从正确的 ViewController.
调用 receivedUVC
如何指向正确的选择器?
谢谢。
MainViewController.swift
class MainViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, BluetoothDelegate {
@IBOutlet weak var peripheralListTableView: UITableView!
@IBOutlet weak var updateButton: UIButton!
let bluetoothManager = BluetoothManager.getInstance()
override func viewDidLoad() {
super.viewDidLoad()
peripheralListTableView.delegate = self
peripheralListTableView.dataSource = self
bluetoothManager.delegate = self
bluetoothManager.discover()
}
func reloadPeripheralList() {
peripheralListTableView.reloadData()
}
func receivedMVC(data: String) {
print("Hello? \(data)")
}
//MARK: - UITableViewDataSource
}
UpdateViewController.swift
class UpdateViewController: UIViewController, BluetoothDelegate {
let bluetoothManager = BluetoothManager.getInstance()
func receivedUVC(data: String) {
print("Allo: \(data)")
}
}
BluetoothManager.swift
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
let stringValue = String(data: characteristic.value!, encoding: String.Encoding.utf8)!
print("Received packet: \(stringValue)")
delegate?.receivedMVC!(data: stringValue) // Delegate method in MainViewController
delegate?.receivedUVC!(data: stringValue) // Delegate method in UpdateViewController
}
[BLE_Tests.MainViewController **receivedUVCWithData:]
这告诉您调用了 MainViewController 方法 receivedUVCWithData:,但是 class 没有实现它。这就是它被称为的原因:
delegate?.receivedUVC!(data: stringValue)
此调用将检查委托是否存在,如果存在,它将向 receivedUVC 发送一条消息,该消息必须(!)存在。所以如果你这样调用它就不会崩溃:
delegate?.receivedUVC?(data: stringValue)
但我问自己为什么要在协议中定义两种不同的方法?在你的协议中定义一个强制的(非可选的)方法,在两个 UIViewControllers 中实现它并在 BluetoothManager.swift 中调用这个方法。然后最后一组委托得到数据。如果两个 ViewControllers 同时存在,您的 BluetoothManager 需要一个 delegate1 和一个 delegate2 以及对两个委托的方法的调用。
目前我的 MainViewController 可以连接到我的蓝牙模块并读取来自它的数据。 现在,我正在尝试从另一个视图控制器读取数据。
我的蓝牙管理器是单例的,所以它不会被多次实例化。为了读取和处理适当的 ViewController 中的数据,我正在考虑使用可选委托。当我到达 receivedMVC(data: String) 时它工作正常但在到达 receivedUVC(data: String)
时崩溃我收到以下错误:
[BLE_Tests.MainViewController receivedUVCWithData:]: unrecognized selector sent to instance 0x100d0a9d0 2017-06-22 16:25:58.634682-0700 BLE_Tests[9544:2692419] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[BLE_Tests.MainViewController **receivedUVCWithData:]: unrecognized selector sent to instance 0x100d0a9d0'
如果我将 receivedUVC(data:String) 添加到我的 MainViewController,它不会崩溃但不会从正确的 ViewController.
调用 receivedUVC如何指向正确的选择器?
谢谢。
MainViewController.swift
class MainViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, BluetoothDelegate {
@IBOutlet weak var peripheralListTableView: UITableView!
@IBOutlet weak var updateButton: UIButton!
let bluetoothManager = BluetoothManager.getInstance()
override func viewDidLoad() {
super.viewDidLoad()
peripheralListTableView.delegate = self
peripheralListTableView.dataSource = self
bluetoothManager.delegate = self
bluetoothManager.discover()
}
func reloadPeripheralList() {
peripheralListTableView.reloadData()
}
func receivedMVC(data: String) {
print("Hello? \(data)")
}
//MARK: - UITableViewDataSource
}
UpdateViewController.swift
class UpdateViewController: UIViewController, BluetoothDelegate {
let bluetoothManager = BluetoothManager.getInstance()
func receivedUVC(data: String) {
print("Allo: \(data)")
}
}
BluetoothManager.swift
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
let stringValue = String(data: characteristic.value!, encoding: String.Encoding.utf8)!
print("Received packet: \(stringValue)")
delegate?.receivedMVC!(data: stringValue) // Delegate method in MainViewController
delegate?.receivedUVC!(data: stringValue) // Delegate method in UpdateViewController
}
[BLE_Tests.MainViewController **receivedUVCWithData:]
这告诉您调用了 MainViewController 方法 receivedUVCWithData:,但是 class 没有实现它。这就是它被称为的原因:
delegate?.receivedUVC!(data: stringValue)
此调用将检查委托是否存在,如果存在,它将向 receivedUVC 发送一条消息,该消息必须(!)存在。所以如果你这样调用它就不会崩溃:
delegate?.receivedUVC?(data: stringValue)
但我问自己为什么要在协议中定义两种不同的方法?在你的协议中定义一个强制的(非可选的)方法,在两个 UIViewControllers 中实现它并在 BluetoothManager.swift 中调用这个方法。然后最后一组委托得到数据。如果两个 ViewControllers 同时存在,您的 BluetoothManager 需要一个 delegate1 和一个 delegate2 以及对两个委托的方法的调用。