SamPenn
SamPenn

Reputation: 13

Why does bluetooth disconnect when I move to a new scene?

I am working on an iOS app where I am trying to connect to a nrf52840 Dev Kit. When I do connect to it on one scene it connects no problem, the debug menu tells me that it connects, when I move to a different scene it disconnects.

I have tried moving the connection to different areas of the code but that hasn't changed anything.


import UIKit
import CoreBluetooth


class ViewController: UIViewController, CBCentralManagerDelegate {


    private var centralManager : CBCentralManager!

    private var blePeripheral : CBPeripheral!

    private var uniqueID : Any!



   // manager = CBCentralManager(delegate: self, queue: nil)

    override func viewDidLoad() {
        super.viewDidLoad()
        print("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
        // Do any additional setup after loading the view, typically from a nib.
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 10.0) {
            print("Connecting to peripheral \(self.peripheral)")
        }
        if(centralManager != nil){
            if isConnectedtoAnything(){
                print("not scanning")
                print(centralManager.debugDescription)
            }else{
                print("scanning")
            }
        }
    }
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOn {
            print("Bluetooth is On")
            centralManager.scanForPeripherals(withServices: nil, options: nil)
        } else {
            print("Bluetooth is not activate")
        }
    }

    @IBAction func StartSearch() {
        print("starting Search")
        centralManager = CBCentralManager(delegate: self, queue: nil, options: nil)
    }

    @IBAction func StopConn() {
        if centralManager.isScanning {
            print("Do Nothing")
        }else{
            print("cancelling Connection")
            centralManager.cancelPeripheralConnection(blePeripheral)
        }
    }

    public func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        print("\nName    : \(peripheral.name ?? "(No name)")")
        if peripheral.name == "Device_Name"{
                print("Found the Device")

            blePeripheral=peripheral
            central.connect(blePeripheral, options: nil)
            central.stopScan()
            if !central.isScanning{
                print("===============================")
                print("Connected Successfuly")
            }
        }

        print("RSSI     : \(RSSI)")
        for ad in advertisementData{
            print("AD Data:     \(ad)")


        }
    }
    func isConnectedtoAnything() ->Bool{
        if centralManager.isScanning {
            print("It is scanning ")
            return false
        }
        else {
            return true
        }
    }



    func peripheral(peripheral: CBPeripheral,
                    didUpdateValueForCharacteristic characteristic: CBCharacteristic,
                    error: NSError?)
    {
        if let error = error {
            print("Failed… error: \(error)")
            return
        }
        print("characteristic uuid: \(characteristic.uuid), value: \(characteristic.value)")
    }

    func centralManager(_ central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral,
                        advertisementData: [NSObject : AnyObject]!, RSSI: NSNumber!)
    {
        print("Peripheral : \(peripheral)")

    }

I just want to the app to maintain the connection to the dev kit

Upvotes: 1

Views: 342

Answers (1)

taserghar
taserghar

Reputation: 370

I am not exactly sure whether is this the problem or not. But it is not a good practice to declare connection handles and its delegate in a view controller. When you move to a new view controller delegates might not get invoked because of viewDidDisappear() been called from that instance.

Rather make a Singleton Class which maintains all required connection objects and delegates within that class only. Then get an instance from the view controller to make a connection. And if you move to a new view controller, again get the instance from the singleton class to send or receive data from the new view controller.

I maintain connections across several view controllers in the same manner.

Upvotes: 1

Related Questions