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.
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.