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!")
}
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With