user12346
user12346

Reputation: 107

Background scan BLE in swift

I am trying to connect with BLE in background but it did not connect in background. It is working when my app is in foreground. I am trying to scan with UUID of the peripheral. Here is the attached code.

 override func viewDidLoad() {
        super.viewDidLoad()

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

    }


    func centralManagerDidUpdateState(_ central: CBCentralManager) {

        var msg = ""

        switch central.state {

            case .poweredOff:
                msg = "Bluetooth is Off"
            case .poweredOn:
                msg = "Bluetooth is On"
                let arrayOfServices: [CBUUID] = [CBUUID(string: "CCAExxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]

                manager?.scanForPeripherals(withServices:arrayOfServices, options: nil)
            case .unsupported:
                msg = "Not Supported"
            default:
                msg = "Not Connected"

        }

        print("STATE: " + msg)

    }

    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {

        print("Name: \(peripheral.name)") //print the names of all peripherals connected.

        //you are going to use the name here down here ⇩

        if peripheral.name == "Name of device" { //if is it my peripheral, then connect

            self.myBluetoothPeripheral = peripheral     //save peripheral
            self.myBluetoothPeripheral.delegate = self

            manager.stopScan()                          //stop scanning for peripherals
            manager.connect(myBluetoothPeripheral, options: nil) //connect to my peripheral

        }
    }

How can resolve it?

Upvotes: 1

Views: 3881

Answers (2)

Deepak Tagadiya
Deepak Tagadiya

Reputation: 2237

Turn on 'Background Modes' Capabilities.

And turn on below two option: 1. User Bluetooth LE accessories. 2. Act as Bluetooth LE accessory.

Do same as Screenshot:

enter image description here

Now BLE is working in background mode in iOS application.

Upvotes: 3

EmirC
EmirC

Reputation: 468

What you have to do is when you instantiate CentralManager you need to instantiate it with a restoration identifier.

Ex:

CBCentralManager(delegate: self,options:
[CBCentralManagerOptionRestoreIdentifierKey: "bleCentralManager"])

This is necessary as in the apple documentation it says "Core Bluetooth preserves the state of only those objects that have a restoration identifier".

Then when your app is relaunched into the background you have to reinstantiate your appropriate central manager with the same restoration identifier inside you appDelegate's application:didFinishLaunchingWithOptions: method.You can get the restoration identifiers like this:

let centralManagerIdentifiers = launchOptions![UIApplicationLaunchOptionsKey.bluetoothCentrals]

Finally in your central managers centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) delegate method you can get a list of all the peripherals the central manager was connected to or was trying to connect to and do whatever want to do in this method.

 func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) {

    let peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey]

}

Upvotes: 0

Related Questions