ios - CoreBluetooth 有时无法检测到 CBPeripheral,除非访问控制中心/通知中心
问题描述
我正在开发一个连接到 BLE 外围设备的应用程序,有时我会遇到一个非常奇怪的问题,即 CentralManager 从未找到外围设备。但是,当在设备上拉下通知中心时,或者在向上滑动控制中心时,外围设备会立即显示并连接。
我试图找到这个问题的原因,但到目前为止我还没有找到任何东西。除了willResignActive
and didBecomeActive
,似乎没有其他生命周期函数被调用(AFAIK),但在这两个函数中,除了打印它们已被调用之外,我没有做任何其他事情。
我已经确保使用self.centralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
以防万一我搞砸了并且没有检测到初始扫描。
有谁知道这可能是什么原因,以及控制中心或通知中心对应用程序的影响如何解决这个问题?
谢谢!
编辑:一些额外的代码可能有助于找到问题。但是,我知道当问题发生时,discoveredPeripheral
两者connectedPeripheral
都是nil
.
didConnect
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
if centralManager.isScanning {
centralManager.stopScan()
}
self.connectedPeripheral = peripheral
self.discoveredPeripheral?.delegate = self
debugPrint("\(Date()): Connected \(peripheral)")
peripheral.discoverServices(nil)
DispatchQueue.main.async {
self.rssiTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.readPeripheralRSSI), userInfo: nil, repeats: true)
}
}
didDiscover
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) {
if peripheral.name == global.qnr && discoveredPeripheral == nil {
centralManager.stopScan()
debugPrint(
"Discovered \(peripheral). " +
"Initiating authentication sequence with \n" +
"\tQNR: \(global.qnr)\n" +
"\tSessionKey: \(global.sessionKey)\n" +
"\tToken: \(global.bluetoothToken)")
if self.discoveredPeripheral == nil || self.discoveredPeripheral != peripheral {
self.discoveredPeripheral = peripheral
self.centralManager.connect(peripheral, options: nil)
}
}
}
startScanning
func scanForPeripherals() {
if !centralManager.isScanning && global.sessionKey != "" {
let services = [CONSTANTS.CBUUID]
self.centralManager.scanForPeripherals(withServices: services, options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
}
}
解决方案
当发现设备时,您必须通知委托人。我就是这样处理的。当我发现然后添加或重新添加时,我删除了以前添加的设备。将发现的设备添加到阵列后,如果您使用 tableView 显示,则重新加载表。
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
if (peripheral.name != nil) {
// remove previously added devices
items.removeAll()
items.append(peripheral)
}
// Set RSSI to custom peripheral signal property
customPeripheral.signal = RSSI
// Notify delegate for change in data.
NotificationCenter.default.post(name: .reload, object: nil)
}
// Extension for reload tableView when peripheral array is updated
extension Notification.Name {
static let reload = Notification.Name("reload")
}
在你的情况下。扫描完成并找到设备后,您会通知连接到您的设备的通知。
// Connect with peripheral
func connectPeripheral(peripheral: CBPeripheral) {
centralManager.connect(peripheral, options: nil)
centralManager.stopScan()
print("Connecting")
}
推荐阅读
- tensorflow - 收到错误“未创建保护程序,因为图中没有要恢复的变量”
- php - 图像垂直显示而不是水平显示
- mysql - 如何使用 MySQL 全文搜索土耳其语字符?
- php - 多个实体的 ApiPlatform PUT 关系(注释)
- wpf - 未评估嵌套 XAML WPF 中的绑定
- macports - 如何在错误情况下中止 macports 端口文件?
- django - 如何在 Next.js 中利用 Django 的身份验证系统?
- c++ - C/C++ 中的 inline void 和 void inline 的区别
- python - 如果没有按钮,如何避免 Selenium 点击功能出错
- docker - 远程 docker-compose 在哪里工作 - 远程或本地