Search code examples
iosobjective-cswiftbluetooth-lowenergycore-bluetooth

Callback from CBCentralManagerDelegate to retrieve CBPeripheral on IOS8


I have a BluetoothManager class managing BTLE communication. I can scan and connect to a CBPeripheral and discover services or characteristics. I have the good callbacks from CBCentralManagerDelegate and CBPeripheralDelegate

When I'm connected to a CBPeripheral, I save the UUIDString in CoreData to retrieve this peripheral when I relaunched the app.

This is my Swift code to retrieve peripherals when I restart the app:

func retrievePeripheralsWithIdentifiers(identifiers: [AnyObject]!){
    let data = self.centralManager.retrievePeripheralsWithIdentifiers(identifiers)

    println("Data retrieved: \(data)")

    for peripheral in data as [CBPeripheral] {

        println("Peripheral : \(peripheral)")
        peripheral.delegate = self
        centralManager.connectPeripheral(peripheral, options: nil)
    }
}

This is what I've got:

Data retrieved: [<CBPeripheral: 0x1669fcd0, identifier = XXXXX, name = Peripheral1, state = disconnected>]
Peripheral : <CBPeripheral: 0x1669fcd0, identifier = XXXXX, name = Peripheral1, state = disconnected>

I can find one of my peripheral without any problem. But when I call the line "centralManager.connectPeripheral(peripheral, options:nil)", I don't have any response.

These methods

func centralManager(central: CBCentralManager!, didRetrievePeripherals peripherals: [AnyObject]!)
func centralManager(central: CBCentralManager!, didConnectPeripheral peripheral: CBPeripheral!)
func centralManager(central: CBCentralManager!, didFailToConnectPeripheral peripheral: CBPeripheral!, error: NSError!)

are not called back to let me know what's wrong. So I can find the good peripheral but I can't connect to it.

However, I have the same code to connect to some peripherals when I'm scanning and it works; my own CBCentralManager has a the good delegate and my peripheral too.

What am I doing wrong?

I'm on Xcode-Beta5 with a iPod-Touch iOS8-Beta5.

Thanks,

Ben

EDIT

Ok, that's more weird

I try this following code from my older app on iOS7 & Objective-C, I saved the UUIDString when I'm connected, and try to retrieve peripherals. It works well: NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

if ([defaults objectForKey:@"UUIDString"]) {
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:[defaults objectForKey:@"UUIDString"]];
    NSArray * data = [self.centralManager retrievePeripheralsWithIdentifiers:@[uuid]];

    if ( [data count] > 0 ){
        self.currentPeripheral = [data objectAtIndex:0];
        [self.currentPeripheral setDelegate:self];

        [self.centralManager connectPeripheral:self.currentPeripheral options:nil];
    }
} else {

    NSLog(@"Scanning started");
    /*...*/
}

That's the same code from my new app on iOS8 & Swift:

    let userDefaults = NSUserDefaults.standardUserDefaults()

    if userDefaults.objectForKey("UUIDString") != nil {

        let uuid = NSUUID(UUIDString: userDefaults.objectForKey("UUIDString") as String)
        let data = self.centralManager.retrievePeripheralsWithIdentifiers([uuid]) as [CBPeripheral]

        if data.count > 0 {

            self.currentPeripheral = data[0]

            println("Current peripheral \(self.currentPeripheral)")
            self.currentPeripheral!.delegate = self
            self.centralManager.connectPeripheral(self.currentPeripheral!, options: nil)
        }
    } else {

        println("Start Scanning")
        /*...*/
    }

I try my old app on iPod Touch iOS7 and it works well. I try my old app on iPod Touch iOS8 and it works also fine. I try my new app on iPod Touch iOS8 and it doesn't work.

I didn't find any differences between the both codes. I can scan, discover and connect peripherals, but connect to retrieved peripherals seems not working on iOS8 & Swift.


Solution

  • It looks like in your original example, you aren't saving a local copy of the CBPeripheral.

    From the CBCentralManager Class Reference - connectPeripheral:

    Pending connection attempts are also canceled automatically when peripheral is deallocated.