In my app, I search for previously connected devices with the delegate method retrieveConnectedPeripheralsWithServices
first, then scan for nearby devices if nothing is found. Here is the code
- (void)searchForPeripherals {
NSLog(@"*** scanning for Bluetooth peripherals... ***");
//Check to see if any devices were connected already
if(self.ourPeripheral != nil) {
[self connectToDevice];
} else {
//Search for previously paired devices...
bool foundPairedDevices = [self checkForAndConnectToPreviouslyPairedDevices];
//None found, scan for new devices nearby...
if(!foundPairedDevices) {
NSLog(@"No paired boxes found, checking device powered state...");
//If the app user has "bluetooth" option turned on
if(self.centralManager.state == CBCentralManagerStatePoweredOn) {
NSLog(@"--- central manager powered on.");
NSLog(@"...begin scanning...");
[self.centralManager scanForPeripheralsWithServices:nil
options:@{CBCentralManagerScanOptionAllowDuplicatesKey: @(YES)}];
//No, user has "bluetooth" turned off
} else {
NSLog(@"--- central manager is NOT powered on.");
}
}
}
}
- (bool)checkForAndConnectToPreviouslyPairedDevices {
NSLog(@"our peripheral device: %@", self.ourPeripheral);
NSArray *dcBoxesFound = [self.centralManager retrieveConnectedPeripheralsWithServices:@[[CBUUID UUIDWithString:SERVICE_UUID]]];
NSLog(@"Previously paired DC boxes?: %@", dcBoxesFound);
//Are there any previously paired devices?
if(dcBoxesFound != nil && [dcBoxesFound count] > 0) {
CBPeripheral *newestBoxFound = [dcBoxesFound firstObject];
newestBoxFound.delegate = self;
self.ourPeripheral = newestBoxFound;
self.deviceUUID = [CBUUID UUIDWithString:[newestBoxFound.identifier UUIDString]];
[self connectToDevice];
return YES;
} else {
return NO;
}
}
- (void)connectToDevice {
if(self.ourPeripheral != nil) {
[self.centralManager connectPeripheral:self.ourPeripheral options:nil];
}
}
- (void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI {
NSLog(@"scanned and found this peripheral: %@", peripheral);
NSLog(@"advertisment data: %@", advertisementData);
if(!self.isConnectedToDevice && [[advertisementData objectForKey:@"kCBAdvDataLocalName"] localizedCaseInsensitiveContainsString:@"dc-"]) {
NSLog(@"\n");
NSLog(@"-------------------------------------------");
NSLog(@"DC peripheral found! Attempting to connect to the following...: %@", peripheral);
peripheral.delegate = self;
self.ourPeripheral = peripheral;
self.deviceUUID = [CBUUID UUIDWithString:[peripheral.identifier UUIDString]];
[self connectToDevice];
NSLog(@"-------------------------------------------");
NSLog(@"\n");
}
}
- (void)centralManager:(CBCentralManager *)central
didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(@"--- didConnectPeripheral");
peripheral.delegate = self;
[peripheral discoverServices:@[[CBUUID UUIDWithString:SERVICE_UUID]]];
}
The Problem
When I start up the app it usually connects just fine. Everything is all good. Then at very unpredictable and odd times the BT connection gets "stuck" somehow. What I mean by stuck is that it never truely connects. The blue light on my box goes on as though the system has connected to it but in my app this is what happens.
1) The retrieveConnectedPeripheralsWithServices
method finds an empty array of previously connected devices, telling the method that called it that there are no previously connected devices found.
2) The scanForPeripheralsWithServices:nil
method is fired and begins scanning with the didDiscoverPeripheral
method.
3) The didDiscoverPeripheral
never even once discovers any boxes nearby with the prefix in kCBAdvDataLocalName
of "dc-" something or other
If I were to go into iOS settings -> bluetooth -> forget this device (have to hit it twice which makes me feel like it's "stuck" somehow) and then actually turn off the BT option all together... Wait 2 seconds and then turn it back on again... then re-launch the application, it all loads fine.
1) The app starts up
2) See's no previously connected devices
3) Scans for peripherals and finds my prefixed box name "dc-whatever"
4) Asks me to pair with BT device and then I have full functionality back
If I then shut down the app and re-launch it, the retrieveConnectedPeripheralsWithServices
finds my previously connected box without trouble and connects seamlessly...
So... what is going on here? Why does it seem to get "stuck" randomly some times?
EDIT:
I do realize that pairing and connecting are not the same thing so some method are named really poorly.