Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disconnect a BLE peripheral in SWIFT

I have some issues to disconnect a BLE peripheral in Swift. First, I tried to use only the cancelPeripheralConnection: function. But if I just call this function, the didDisconnectPeripheral function is never called. So I tried to follow Apple's reference guide. 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?

EDIT 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):

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

But anyway, if I call this function, the didDisconnectPeripheral function isn't called. When I put the function in the BluetoothManager class e.g. after I discovered the last characteristic, everything works.

EDIT 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...

}
like image 781
PascalS Avatar asked Oct 21 '15 15:10

PascalS


1 Answers

To your first doubt, yes we should deregister from subscribed characteristics before disconnecting from peripheral for a reason given in 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.

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. This deal works great and help troubleshooting confined to one class only. You can try this out.

like image 88
Abhinav Avatar answered Oct 14 '22 08:10

Abhinav