swiftcore-bluetoothbluetooth-lowenergycbperipheralcbperipheralmanager

Peripheral not connecting - Swift


Within my Swift app, I have a view that is supposed to find a bluetooth device and connect to it. The bluetooth device is powered on. I am able to scan and find the device, after which I call on the function to connect to it, but I get no feedback. I am not sure why it is not able to connect.

Neither didFailToConnectPeripheral or didConnectPeripheral are returning any values.

How do I get this to work?

import UIKit
import CoreBluetooth

class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate {

    var manager: CBCentralManager!


    override func viewDidLoad() {
        super.viewDidLoad()
        manager = CBCentralManager (delegate: self, queue: nil)
    }


    func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {

        print("Peripheral: \(peripheral)")

        manager.connectPeripheral(peripheral, options:nil)

        manager.stopScan()

    }



    func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) {
        print("connected!")
    }

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


    func centralManager(central: CBCentralManager,
        didFailToConnectPeripheral peripheral: CBPeripheral, error: NSError?) {
            print("failed")
    }


    func centralManagerDidUpdateState(central: CBCentralManager) {
        print("Checking")
        switch(central.state)
        {
        case.Unsupported:
            print("BLE is not supported")
        case.Unauthorized:
            print("BLE is unauthorized")
        case.Unknown:
            print("BLE is Unknown")
        case.Resetting:
            print("BLE is Resetting")
        case.PoweredOff:
            print("BLE service is powered off")
        case.PoweredOn:
            print("BLE service is powered on")
            print("Start Scanning")
            manager.scanForPeripheralsWithServices(nil, options: nil)
        default:
            print("default state")
        }
    }
}

Solution

  • You need to retain the CBPeripheral object that you are trying to connect to, otherwise it is released once the delegate method didDiscoverPeripheral returns.

    import UIKit
    import CoreBluetooth
    
    class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate {
    
        var manager: CBCentralManager!
        var connectingPeripheral: CBPeripheral?
    
    
        override func viewDidLoad() {
            super.viewDidLoad()
            manager = CBCentralManager (delegate: self, queue: nil)
        }
    
    
        func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
    
            print("Peripheral: \(peripheral)")
    
            self.connectingPeripheral=peripheral    
    
            manager.connectPeripheral(peripheral, options:nil)
    
            manager.stopScan()
        }
    
    ...
    
    }