I have run into a problem where establishing a connection to my device while my app is running in the background is very inconsistent. I have a device that will send over some data (after the user selects to do so) after which it will disconnect. After reading through the mailing list archives and stackoverflow I went with
1. Saving the UUID of the device after establishing a connection once using a scan
2. After that, Once a disconnect happens (or the app is launched) I call retrievePeripherals with that UUID and try to make a connect call
When the app is in the background it sometimes ends up in an endless connect/disconnect loop until the device times out.
I have added logging to all the delegate methods and the output is as follows (I have also attached some sample code after)
Bad Attempt:
2013-07-24 11:59:29.759 AppName[23779:907] Peripheral connected: DeviceName
2013-07-24 11:59:30.125 AppName[23779:907] Peripheral disconnected: DeviceName
2013-07-24 11:59:30.129 AppName[23779:907] Attempting to connect to saved device UUID: 038B1260-2650-CB7B-6C4A-BB20DF6CEA0D
2013-07-24 11:59:30.131 AppName[23779:907] Retrieved peripheral: 1 - (
"<CBConcretePeripheral: 0x210aa950 UUID = <CFUUID 0x253931c0> 038B1260-2650-CB7B-6C4A-BB20DF6CEA0D, Name = \"DeviceName\", IsConnected = NO>"
)
2013-07-24 11:59:31.129 AppName[23779:907] Peripheral connected: DeviceName
2013-07-24 11:59:31.898 AppName[23779:907] Peripheral disconnected: DeviceName
2013-07-24 11:59:31.900 AppName[23779:907] Attempting to connect to saved device UUID: 038B1260-2650-CB7B-6C4A-BB20DF6CEA0D
2013-07-24 11:59:31.903 AppName[23779:907] Retrieved peripheral: 1 - (
"<CBConcretePeripheral: 0x210aa950 UUID = <CFUUID 0x253931c0> 038B1260-2650-CB7B-6C4A-BB20DF6CEA0D, Name = \"DeviceName\", IsConnected = NO>"
)
This loops till the device times out.
Successful Attempt:
2013-07-24 12:36:29.175 AppName[23883:907] Attempting to connect to saved device UUID: 038B1260-2650-CB7B-6C4A-BB20DF6CEA0D
2013-07-24 12:36:29.246 AppName[23883:907] Peripheral connected: DeviceName
2013-07-24 12:36:29.252 AppName[23883:907] Retrieved peripheral: 1 - (
"<CBConcretePeripheral: 0x1ed36740 UUID = <CFUUID 0x1ed859d0> 038B1260-2650-CB7B-6C4A-BB20DF6CEA0D, Name = \"DeviceName\", IsConnected = YES>"
)
2013-07-24 12:36:29.413 AppName[23883:907] Peripheral disconnected: DeviceName
2013-07-24 12:36:29.417 AppName[23883:907] Attempting to connect to saved device UUID: 038B1260-2650-CB7B-6C4A-BB20DF6CEA0D
2013-07-24 12:36:29.421 AppName[23883:907] Retrieved peripheral: 1 - (
"<CBConcretePeripheral: 0x1f8295b0 UUID = <CFUUID 0x1f852740> 038B1260-2650-CB7B-6C4A-BB20DF6CEA0D, Name = \"DeviceName\", IsConnected = NO>"
)
2013-07-24 12:37:22.486 AppName[23883:907] Peripheral connected: DeviceName
2013-07-24 12:37:23.362 AppName[23883:907] Service found with UUID: Unknown (<aec465ca 9c7d4e7f bf00ec05 4692a1da>)
2013-07-24 12:37:23.811 AppName[23883:907] Notification characteristic discovered for DeviceName
2013-07-24 12:37:24.373 AppName[23883:907] Received new packet...
Code Snippet
- (void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals
{
#ifdef BLUETOOTH_DEVICE_LOGGING
NSLog(@"Retrieved peripheral: %u - %@", [peripherals count], peripherals);
#endif
CBPeripheral* peripheral = [peripherals objectAtIndex:0];
if ([peripheral isConnected])
return;
if (![_retrievedPeripheral isEqual: peripheral])
{
[self clearAndReleaseRetrievedPeripheral];
_retrievedPeripheral = peripheral;
[_retrievedPeripheral retain];
}
else
{
#ifdef BLUETOOTH_DEVICE_LOGGING
NSLog(@"Retrieved peripheral is the same as the one passed in to didRetrievePeripherals")
#endif
}
[[self bluetoothCentralManager] connectPeripheral: peripheral options: nil];
}
- (void) onDisconnectPeripheral: (CBPeripheral *)aPeripheral error:(NSError *)error
{
#ifdef BLUETOOTH_DEVICE_LOGGING
NSLog(@"Peripheral disconnected: %@", aPeripheral.name);
#endif
[self clearAndReleasePeripheral];
[self connectToSavedDevices];
}
- (void) connectToSavedDevices
{
NSString* deviceUUID = [self getBluetoothDeviceConnectionUUID];
if (deviceUUID != nil)
{
#ifdef BLUETOOTH_DEVICE_LOGGING
NSLog(@"Attempting to connect to saved device UUID: %@", deviceUUID);
#endif
CFUUIDRef uuid = CFUUIDCreateFromString(NULL, (CFStringRef)deviceUUID);
if (uuid)
{
[[self bluetoothCentralManager] retrievePeripherals:[NSArray arrayWithObject:(id)uuid]];
CFRelease(uuid);
}
}
}
Any thoughts on what I might be doing wrong?
Thanks
Raj