在 SWIFT 中断开 BLE 外围设备

Disconnect a BLE peripheral in SWIFT

我在 Swift 中断开 BLE 外围设备时遇到一些问题。首先,我尝试只使用 cancelPeripheralConnection: 函数。但是如果我只是调用这个函数,didDisconnectPeripheral 函数就永远不会被调用。所以我试着遵循 Apple's 参考指南。据说,您应该在断开连接之前删除所有通知。这真的有必要吗?是否有可能一步取消所有通知?我设置了很多通知,所以我必须搜索很多服务和特性来重置它们。我想,这不可能是 "well done" 解决方案。

编辑: 好的,我发现 cancelPeripheralConnection 工作得很好,如果我在我的 BluetoothManager class 中调用它,其中包含 CBCentralManagerCBPeripheralDelegate...有没有办法在这个函数之外断开与外围设备的连接?

编辑 4:

import UIKit

class ValueCollectionView: UICollectionViewController
{
    var valueCollectionViewCell: ValueCollectionViewCell = ValueCollectionViewCell()
    var bluetoothManager: BluetoothManager = BluetoothManager()

    override func viewDidLoad()
    {
        super.viewDidLoad()
        self.navigationItem.hidesBackButton = true
        let newBackButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "back:")
        self.navigationItem.leftBarButtonItem = newBackButton;
    }

    override func didReceiveMemoryWarning()
    {
        super.didReceiveMemoryWarning()
    }

    func back(sender: UIBarButtonItem)
    {
        bluetoothManager.disconnectPeripheral(selectedPeripheralIndex!)
        self.navigationController?.popViewControllerAnimated(true)
    }
//Some Collection View functions...
}

这是我对 disconnectPeripheral 函数的实现(集成在 BluetoothManager class 中):

func disconnectPeripheral(peripheralIndex: Int)
{
    CBmanager.cancelPeripheralConnection(peripheralArray![peripheralIndex].peripheral)
}

但是无论如何,如果我调用这个函数,didDisconnectPeripheral 函数不会被调用。当我将函数放入 BluetoothManager class 时,例如在我发现最后一个特征后,一切正常。

编辑 5:

class BluetoothManager: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate
{
    var CBmanager: CBCentralManager = CBCentralManager()

    override init()
    {
        super.init()
        self.CBmanager = CBCentralManager(delegate: self, queue: nil)
    }

    func connectPeripheral(peripheralIndex: Int)
    {
        CBmanager.connectPeripheral(peripheralArray![peripheralIndex].peripheral, options: nil)
    }

    func disconnectPeripheral(peripheralIndex: Int)
    {
        CBmanager.cancelPeripheralConnection(peripheralArray![peripheralIndex].peripheral)
    }

//The other CentralManager functions...

}

对于您的第一个疑问,是的,我们应该在断开与外围设备的连接之前取消注册订阅的特性,原因在 Apple Documentation 中给出:

Note: The cancelPeripheralConnection: method is nonblocking, and any CBPeripheral class commands that are still pending to the peripheral you’re trying to disconnect may or may not finish executing. Because other apps may still have a connection to the peripheral, canceling a local connection does not guarantee that the underlying physical link is immediately disconnected. From your app’s perspective, however, the peripheral is considered disconnected, and the central manager object calls the centralManager:didDisconnectPeripheral:error: method of its delegate object.

现在,回到你的另一个问题 -

Is there a way to disconnect to a peripheral outside of this function?

您需要断开它与您实例化并开始连接的实例的连接。只要您可以在同一个对象上调用取消,它就应该可以工作。

myCentralManager.cancelPeripheralConnection(peripheral)

在我的应用程序中,我不得不使用来自许多不同 classes 的 BLE 功能,这导致我编写了一个单例 MyBLEManager 并且所有 classes 都进入了这个单例对于所有 BLE 相关活动。这笔交易非常有效,并且有助于仅限于一个 class 的故障排除。你可以试试这个。