CoreBluetooth 有时无法检测到 CBPeripheral,除非访问控制中心/通知中心
Posted
技术标签:
【中文标题】CoreBluetooth 有时无法检测到 CBPeripheral,除非访问控制中心/通知中心【英文标题】:CoreBluetooth sometimes not detecting CBPeripheral unless accessing Control Center/Notification Center 【发布时间】:2018-06-02 13:53:47 【问题描述】:我正在开发一个连接到 BLE 外围设备的应用程序,有时我会遇到一个非常奇怪的问题,即 CentralManager 从未找到外围设备。但是,当在设备上拉下通知中心时,或者在向上滑动控制中心时,外围设备会立即显示并连接。
我试图找出这个问题的原因,但到目前为止我还没有找到任何东西。除了willResignActive
和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])
【问题讨论】:
discoveredPeripheral
和 connectedPeripheral
为零,因为根本没有调用方法 didConnect
。这个didConnect
方法在你连接到设备时被调用。
您正在使用scanForPeripherals()
方法扫描设备。接下来发生什么?您如何与设备连接?
在scanForPeripherals()
开始扫描后,我应该在我的didDiscover peripheral
函数上得到回调(我也在那里connect
),但是,我有时没有得到使用正确的name
对该函数的任何回调,直到我滑动通知中心或控制中心(触发willResignActive()
)
【参考方案1】:
您必须在发现设备时通知代理。我就是这样处理的。当我发现然后添加或重新添加时,我删除了以前添加的设备。将发现的设备添加到阵列后,如果您使用 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")
【讨论】:
我已经这样做了。我过滤期望的名称,连接到它,发现服务/特征,然后告诉我的代表。所以不幸的是,我认为这不会解决它。 你试过了吗?而且,如果您不向我们展示您的代码,将很难解决您的问题。你做了什么,没有做什么。 是否在表格中显示设备列表? 不,它应该连接的只有一个设备,即具有特定名称的设备(实际上是一辆车),所以我只需要知道该特定外围设备的信息。 同样,我还用我使用的一些代码更新了我的答案。问题不是我没有告诉我的代表,而是我的 CentralManager 有时找不到外围设备。当我检查我班级的局部变量(discoveredPeripheral
和connectedPeripheral
)时,它们会一直保持nil
直到强制关闭,或者直到控制中心/通知中心出现...以上是关于CoreBluetooth 有时无法检测到 CBPeripheral,除非访问控制中心/通知中心的主要内容,如果未能解决你的问题,请参考以下文章
如何获取/查找 CoreBluetooth.Framework?
express-ejs-layout 有时无法检测到传递参数
CoreBluetooth:在 CBPeripheralStateConnecting 中的 didDisconnectPeripheral 回调