Sagar
Sagar

Reputation: 1304

didRangeBeacons not showing any beacon devices

I am new to beacon programming.

I searched on SO and got lots of help, but stuck at one point.

as my didRangeBeacons is getting called, but it is always showing null array for beacons.

Here is my code for didDiscoverPeripheral

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:peripheral.identifier.UUIDString];

    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"com.XXXXXX.beacon"];

    self.beaconRegion.notifyEntryStateOnDisplay = YES;

    [self.locationManager startMonitoringForRegion:self.beaconRegion];
    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];

    self.locationManager.delegate = self;
}

and this is code for didRangeBeacons

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
CLBeacon *foundBeacon = [[CLBeacon alloc] init];
    foundBeacon = [beacons firstObject];
NSString *uuid = foundBeacon.proximityUUID.UUIDString;
     NSString *major = [NSString stringWithFormat:@"%@", foundBeacon.major];
     NSString *minor = [NSString stringWithFormat:@"%@", foundBeacon.minor];

     NSLog(@"%@",uuid);
     NSLog(@"%@",major);
     NSLog(@"%@",minor);
}

this always gives me null values.. whats getting wrong. Please help...

Upvotes: 1

Views: 802

Answers (2)

davidgyoung
davidgyoung

Reputation: 64916

The device is not detecting any beacons. The line foundBeacon = [beacons firstObject]; is returning Nil, you can see this if you change your code to:

{
CLBeacon *foundBeacon = [beacons firstObject];
if (foundBeacon != Nil) {
   NSString *uuid = foundBeacon.proximityUUID.UUIDString;
   NSString *major = [NSString stringWithFormat:@"%@", foundBeacon.major];
   NSString *minor = [NSString stringWithFormat:@"%@", foundBeacon.minor];

   NSLog(@"%@",uuid);
   NSLog(@"%@",major);
   NSLog(@"%@",minor);
  }
  else {
    NSLog("No beacons detected");
  }
}

It is unclear why it is not detecting beacons, but the most common reason is that the identifiers in the CLBeacon region you use to start ranging do not match what the beacon is transmitting. It may help to show this setup code.

It is worth noting that the didDiscoverPeripheral code shown is not necessary for detecting beacons and has no role in basic beacon detection.

UPDATE: The comment of the questioner below is critical:

I am using didDiscoverPeripheral method to find the available BLE devices and to get those UUID and then setting then I am setting startMonitoringForRegion and startRangingBeaconsInRegion. As I am unaware of UUID that is for device

The above technique will not work, because the UUID returned by didDiscoverPeripheral has nothing to do with the beacon ProximityUUID, even though both UUIDs use the same string format and superficially look similar. There is no public API in iOS to get a beacon's ProximityUUID without knowing it in advance. See my blog post here for more info: http://developer.radiusnetworks.com/2013/10/21/corebluetooth-doesnt-let-you-see-ibeacons.html

Upvotes: 0

heypiotr
heypiotr

Reputation: 2149

The problem is, you're using peripheral.identifier as the UUID of the beacon region you're ranging and monitoring for.

It's deceptive, because they both use the same Version 4 UUID format, but Peripheral UUID and iBeacon UUID are two completely different things:

  • Peripheral UUID identifies a particular BLE device. However, even for the BLE same device, its peripheral UUID will differ from iPhone to iPhone, and might also change after you either the iPhone, or the Bluetooth subsystem gets rebooted.

    You can think of it as an ephemeral identifier that an iPhone assigns to a BLE device so that you can identify it between Core Bluetooth calls on that iPhone.

    This is part of the Core Bluetooth subsystem, which is intended for use with any non-iBeacon BLE devices.

  • iBeacon UUID is just a static value which an iBeacon device broadcasts. It's going to be the same for all iPhones that discover it, because unlikely Peripheral UUID, this is not something that the iPhone assigns, but rather a property of the beacon itself.

    On the iOS side, this is part of the Core Location subsystem, which is intended for use with iBeacon.

In your CLBeaconRegion, you need to use the iBeacon UUID of your beacons, not the Peripheral UUID. Consult with the vendor of your beacons on how to discover the iBeacon UUID of your beacons. Most vendors simply assign a pre-defined static value to all the beacons they produce (but you can often change it to your own).

Note that you need to know the iBeacon UUID upfront to be able to discover iBeacons with that UUID. There's no way around that.


I'm also not exactly sure why you're starting iBeacon ranging/monitoring in response to a Core Bluetooth scan—unless you have a very specific reason, you don't need to do it this way. You can just move out all of your code out of the didDiscoverPeripheral method.

Upvotes: 2

Related Questions