iHarshil
iHarshil

Reputation: 779

Core Bluetooth: CBPeripheral disconnects unknowingly and not getting any call to didDisconnectPeripheral

I have 3 ViewControllers. 1)Home VC 2) Scan VC 3) Connect VC

Steps: From Home VC, I push to Scan VC for scanning the available BLE Devices.

Scan VC: I have all the BLE Communication code here:

override func viewDidLoad() {
        super.viewDidLoad()

            AppConstants.sharedInstance.centralManager = CBCentralManager(delegate: self, queue: nil) // created global Instance for central Manager and assigned it here
    }

Above will call centralManagerDidUpdateState(_ central: CBCentralManager) Where I am checking all the state for BLUETOOTH. And if,

case .poweredOn:
            btnRefresh.isEnabled = true
            print("central.state is .poweredOn...")

            startScan()
        }

then I Scan for the Devices.

Once I get my device, I connect to it from list of scanned devices,

Then I successfully Connect to that Device it goes to Connect VC.

Till here everything is great.

But real problem starts when

1) I pop from Connect VC to Scan VC and then again Pop to HOMEVC And

2) Then I again push from Home VC to Scan VC

Scan VC: This will call and assign the Delegate to my global CentralManager and as soon as it assign the delegate again, It disconnects the previous connection. (Even I don't get any didDisconnectPeripheral Call)

override func viewDidLoad() {
        super.viewDidLoad()

            AppConstants.sharedInstance.centralManager = CBCentralManager(delegate: self, queue: nil) // Here when I come again it disconnects old connection.
    }

I don't know what's the issue. I am not getting any errors. Please Help...

Upvotes: 0

Views: 1233

Answers (2)

iHarshil
iHarshil

Reputation: 779

No Worries. I found my way to workaround. Thanks to @Natrajan for giving me some idea about it.

override func viewDidLoad() {
            super.viewDidLoad()


            if AppConstants.sharedInstance.centralManager == nil{
                AppConstants.sharedInstance.centralManager = CBCentralManager(delegate: self, queue: nil)
            }
            else
            {
                centralManagerDidUpdateState(AppConstants.sharedInstance.centralManager!)
            } 
}

This serves my purpose and I can Check the Bluetooth State and Scan accordingly (Everytime pushing to the Scan VC)

Yuppieee... :)

Upvotes: 0

Natarajan
Natarajan

Reputation: 3271

I think, Since you are reassigning CBCentralManager to AppConstants.sharedInstance.centralManager in viewDidLoad, CBCentralManager is getting destroyed and disconnected.

Also As it's destroyed, it is not returning any delegate callbacks.

So Can you try to initialize the CBCentralManager only once as like below and disconnect when required?

Example:

override func viewDidLoad() {
        super.viewDidLoad()


        if AppConstants.sharedInstance.centralManager == nil{

            AppConstants.sharedInstance.centralManager = CBCentralManager(delegate: nil, queue: nil)
        }

        AppConstants.sharedInstance.centralManager.delegate = self
    }

Upvotes: 1

Related Questions