简体   繁体   English

断开SWIFT中的BLE外设

[英]Disconnect a BLE peripheral in SWIFT

I have some issues to disconnect a BLE peripheral in Swift. 我在Swift中断开BLE外设有一些问题。 First, I tried to use only the cancelPeripheralConnection: function. 首先,我尝试仅使用cancelPeripheralConnection:函数。 But if I just call this function, the didDisconnectPeripheral function is never called. 但是,如果我只调用此函数,则永远不会调用didDisconnectPeripheral函数。 So I tried to follow Apple's reference guide. 所以我试着遵循Apple的参考指南。 There is say's, that you should delete every notifications before disconnecting. 有人说,你应该在断开连接之前删除每个通知。 Is this really necessary? 这真的有必要吗? And is there a possibility to cancel all notifications in one step? 是否有可能一步取消所有通知? I set up a lot of notifications, so I have to search in many services and characteristics to reset them. 我设置了很多通知,因此我必须搜索许多服务和特征才能重置它们。 I guess, that can't be a "well done" solution. 我想,这不是一个“做得好”的解决方案。

EDIT: Okay I figured out, that the cancelPeripheralConnection works pretty well, if I call it in my BluetoothManager class, where CBCentralManager and CBPeripheralDelegate are included... Is there a way to disconnect to a peripheral outside of this function? 编辑:好的,我发现,如果我在我的BluetoothManager类中调用了cancelPeripheralConnection ,那么它包含了CBCentralManagerCBPeripheralDelegate ......有没有办法断开这个函数之外的外围设备?

EDIT 4: 编辑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...
}

And this is my implementation of the disconnectPeripheral function (integrated in the BluetoothManager class): 这是我执行的disconnectPeripheral功能(集成在BluetoothManager类中):

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

But anyway, if I call this function, the didDisconnectPeripheral function isn't called. 但无论如何,如果我调用此函数,则不会调用didDisconnectPeripheral函数。 When I put the function in the BluetoothManager class eg after I discovered the last characteristic, everything works. 当我将该功能放入BluetoothManager类时,例如在我发现最后一个特征之后,一切正常。

EDIT 5: 编辑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...

}

To your first doubt, yes we should deregister from subscribed characteristics before disconnecting from peripheral for a reason given in Apple Documentation : 对于您的第一个疑问,是的,我们应该在断开外围设备之前取消注册,因为Apple文档中给出了一个原因:

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. 注意: cancelPeripheralConnection:方法是非阻塞的,任何仍在等待您尝试断开的外围设备的CBPeripheral类命令可能会也可能不会执行。 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. 但是,从您的应用程序的角度来看,外围设备被视为断开连接,并且中央管理器对象调用centralManager:didDisconnectPeripheral:error:其委托对象的方法。

Now, coming to your other question - 现在,来看你的另一个问题 -

Is there a way to disconnect to a peripheral outside of this function? 有没有办法断开此功能以外的外围设备?

You need to disconnect it from the instance you instantiated and started connection on. 您需要将其与实例化的实例断开连接并开始连接。 As long as you can call the cancellation on the same object it should work. 只要你可以在同一个对象上调用取消它就可以工作。

myCentralManager.cancelPeripheralConnection(peripheral)

In my application, I had to use BLE features from many different classes which led me to write a singleton MyBLEManager and all the classes were coming to this singleton for all BLE related activities. 在我的应用程序中,我不得不使用来自许多不同类的BLE功能,这使我编写了一个单独的MyBLEManager ,所有类都来到了这个单例中,用于所有与BLE相关的活动。 This deal works great and help troubleshooting confined to one class only. 这笔交易非常有用,只能帮助排除一个课程。 You can try this out. 你可以尝试一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM