如何知道 CBPeripheral 何时不再可用

Posted

技术标签:

【中文标题】如何知道 CBPeripheral 何时不再可用【英文标题】:How to know when CBPeripheral is no longer available 【发布时间】:2018-01-30 20:32:21 【问题描述】:

有没有办法检查 CBPeripheral 是否仍然可以连接?

我使用CBCentralManager 扫描外围设备,它会在didDiscover peripheral: 中返回我的外围设备。

如果我关闭并再次打开作为外围设备的物理设备,didDiscover peripheral: 不会再次受到攻击。

此外,如果我在计时器上调用 centralManager.retrievePeripherals(),外围设备将永远不会消失,尽管已关闭很长时间。

【问题讨论】:

【参考方案1】:

当调用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()返回不可用的外围设备,我不知道如何解决。

【讨论】:

以上是关于如何知道 CBPeripheral 何时不再可用的主要内容,如果未能解决你的问题,请参考以下文章

操作系统如何知道进程何时应该处于阻塞状态?

HTML - 我如何知道所有帧何时加载?

同一设备的多个 CBPeripheral

如何知道 UICollectionView 何时完成布局?

此 IfxTransaction 已完成;它不再可用

如何知道 cocoahttpserver 何时启动