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.
Please check whether you save local copy of CBPeripheral object or not.
You must save local copy of peripheral to avoid dealloc after finishing call back function.
If peripheral object dealloc before calling didConnect peripheral callback, core bluetooth automatically cancels pending connection request.
Even having reference of peripheral last time connected, i was facing issue. What trick worked is first get previously connected peripheral using identifier by calling
retrievePeripheralsWithIdentifiers
.
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