2

I am scanning for bluetooth devices. For that I am using CBCentralManager, like so

- (void)startScanning
{
    [self.centralManager scanForPeripheralsWithServices:nil options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];
}

- (void)centralManager:(CBCentralManager *)central
 didDiscoverPeripheral:(CBPeripheral *)peripheral
     advertisementData:(NSDictionary *)advertisementData
                  RSSI:(NSNumber *)RSSI
{
    NSLog(@"\n%@, rssi: %@", peripheral.identifier.UUIDString, RSSI);
    // do stuff
}

I am using Estimote app to simulate a Beacon on other device. The console output looks like that:

2017-07-26 14:43:56.711830 ExampleApplication[445:55698] peripheral:
6A3E0CB4-74BB-4472-98AA-0C9DEB1D4551, rssi: -28

Everything is fine so far.

Now, I want to scan for bluetooth devices also when app is in background. For that, I added such property to Info.plist

<key>UIBackgroundModes</key>
<string>bluetooth-central</string>

Also, I've read that it's not possible to scan for bluetooth devices in background when passing nil as serviceUUIDs, so I take a previously discovered peripheral's UUID and pass it to CBCentralManager

CBUUID *uuid = [CBUUID UUIDWithString:@"6A3E0CB4-74BB-4472-98AA-0C9DEB1D4551"];
[self.centralManager scanForPeripheralsWithServices:@[uuid] options:options];

And there's the problem - didDiscoverPeripheral is never called anymore, even when app is in foreground. What is the reason? I used the UUID of the device that was discovered before with no issues, but not it's not. Any ideas?

mag_zbc
  • 6,801
  • 14
  • 40
  • 62
  • You need to scan for the uuid of a service being advertised by the peripheral, not the uuid of the peripheral. The uuid of the peripheral can change and different iOS devices will see different uuids for the same peripheral, but the service peripheral is consistent. – Paulw11 Jul 26 '17 at 13:07
  • The problem is that for any peripheral I receive, the `services` property is empty – mag_zbc Jul 26 '17 at 13:19
  • @mag_zbc If your peripheral doesn't put in its advertisement that is has some service (by giving it's service UUID), you can't scan specially for it, because if it doesn't advertise it, you need to connect and then scan its services. – Larme Jul 26 '17 at 14:44

2 Answers2

0
-(void)centralManagerDidUpdateState:(CBCentralManager *)central {

if (central.state != CBCentralManagerStatePoweredOn) {
    return;
}
if (central.state == CBCentralManagerStatePoweredOn) {
    [_centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:@"0x180A"]] options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @YES}];
    NSLog(@"Start scanning");
}
}

You can check like this. It can help you to figure out what's the issue

Edit :

Well, if you have tried above code.

Then the ideal way is working with new piece of code in swift as scanForPeripheralsWithServices is Deprecated.

Use : something like this to check out func scanForPeripherals(withServices serviceUUIDs: [CBUUID]?, options: [String : Any]? = nil)

Otherwise it may be a possibility that your hardware is now right or broadcasting correctly.

cole
  • 3,147
  • 3
  • 15
  • 28
  • Device Information org.bluetooth.service.device_information 0x180A – cole Jul 26 '17 at 13:09
  • I check this already. And it doesn't explain why I can discover peripherals just fine when passing `nil` as `serviceUUIDs` – mag_zbc Jul 26 '17 at 13:16
0

iBeacons, if they don't advertise any other services, cannot be scanned in the background using Core Bluetooth. They can only be scanned using Core Location.

pipacs
  • 1,049
  • 11
  • 25