有没有办法检查CBPeripheral是否实际上仍然可以连接?
我使用CBCentralManager
扫描外围设备,它将在didDiscover peripheral:
中返回我的外围设备。
如果我关闭并重新打开外围设备的物理设备,则didDiscover peripheral:
不会再次受到攻击。
同样,如果我在定时器上调用centralManager.retrievePeripherals()
,即使长时间关闭,外围设备也不会消失。
最佳答案
调用scanForPeripherals
时,您将CBCentralManagerScanOptionAllowDuplicatesKey
传递为true
:
centralManager.scanForPeripherals(withServices: yourUUIDs, options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
这样,将多次调用
didDiscoverPeripheral
,通常用于更新RSSI,但是如果您跟踪上一次“发现”每个外围设备的时间,则可以删除长时间不活动的外围设备。如果将已连接的外围设备(例如与
retrieveConnectedPeripherals
连接的设备)保持在同一阵列中,则还必须跟踪我们应该从中更新哪些外围设备。在此示例中,我通过检查RSSI是否为nil
来进行此操作。例:
var peripherals = [(peripheral: CBPeripheral, lastUpdate: Date!)]()
var inactivityTimer: Timer?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
centralManager.scanForPeripherals(withServices: yourUUIDs, options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
inactivityTimer?.invalidate() // prevent duplicates
inactivityTimer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(inactivityCheck), userInfo: nil, repeats: true)
}
@objc func inactivityCheck() {
// reversed because we're removing stuff
for i in (0..<peripherals.count).reversed() {
if peripherals[i].RSSI != nil && peripherals[i].lastUpdate.timeIntervalSinceNow < -2 { // 2s max inactivity
peripherals.remove(at: i)
tableView.reloadData()
}
}
}
func serialDidDiscoverPeripheral(_ peripheral: CBPeripheral, advertisementData: [String : Any]?, RSSI: NSNumber?) {
// check for duplicates
if let i = peripherals.index(where: ({ $0.peripheral === peripheral })) {
// update
peripherals[i].RSSI = RSSI
peripherals[i].lastUpdate = Date()
tableView.reloadData()
} else {
// add
peripherals.append((peripheral, advertisementData, RSSI, Date()))
peripherals.sort { ($0.RSSI?.floatValue ?? 0) > ($1.RSSI?.floatValue ?? 0) } // optionally sort array to signal strength
tableView.reloadData()
}
}
编辑:至于
centralManager.retrievePeripherals()
返回不可用的外围设备,我不知道如何解决。