Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bluetooth didConnect or didFailToConnect not called Xcode 9.2 with iOS 11.1.2

I am having the problem with Xcode 9.2 and iOS 11.1.2,"didDiscover" is working fine and my peripheral is saved in an array before I call connect, but "didConnect" or "didFailToConnect" not called, so the peripheral state will stay at "connecting"... Please help

var manager: CBCentralManager!

override func viewDidLoad() {
    super.viewDidLoad()
    manager = CBCentralManager(delegate: self, queue: nil)
    //manager = CBCentralManager (delegate: self, queue: DispatchQueue.main)
    //manager = CBCentralManager.init(delegate: self, queue: nil, options:[:])
    //manager.delegate = self
}

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
    guard let name = peripheral.name else { return }
    print("BR peripheral.name = \(name), rssi = \(RSSI), adertisementData = \(advertisementData)")

    if (peripheral.name?.hasPrefix("testBT"))! {
        peripheralArray.append(peripheral)
        manager.connect(peripheralArray.first!, options: [:])
        print("Connecting to peripheral \(peripheral)")
    }
}

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
    print("BT connected!")
    manager.stopScan()
    peripheral.delegate = self
    peripheral.discoverServices(nil)
}

func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
    print("BT disconnected!")
}

func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
    print("BT failed!")
}
like image 569
Sen-He Lee Avatar asked Oct 28 '22 22:10

Sen-He Lee


1 Answers

Try making variable global:

var myPeripheral:CBPeripheral?

Than, in your code edit it:

if (peripheral.name?.hasPrefix("testBT"))! {
        myPeripheral = peripheral
       //HERE WRITE DELEGATE, NOT IN didConnect
        myPeripheral!.delegate = self
        //peripheralArray.append(myPeripheral)
        manager.connect(myPeripheral!, options: nil)
        print("Connecting to peripheral \(peripheral)")
    }

Now I think it should work. I would also start scanning on centralManagerDidUpdateState to make sure bluetooth is working, smth like:

func centralManagerDidUpdateState(_ central: CBCentralManager) {
   switch central.state{
     case .poweredOn:
        startScan() // own method where i start scanning
     case .poweredOff:
        print("blth powered off")
     case .unsupported:
        print("bltyh noit supported")
   }
}

etc. there is more states, you can check it in documentation. The centralManagerDidUpdateState method is beeing called after initializing in vievDidLoad your CBCentralManager var (manager = CBCentralManager(delegate: self, queue: nil))

Hope it helps

BTW, you are making an array to store there connected peripherals. Just have in mind that whenever you return from the controller where you store that array and go back to it that array will be empty again. That's why if you need your bluetooth class working globally I would suggest you to make a BluetoothService class that would have a Singleton implemented and you could access any state anywhere in your project

like image 172
M. Wojcik Avatar answered Nov 02 '22 14:11

M. Wojcik