locationManager:didRangeBeacons method not detecti

2019-07-08 08:07发布

问题:

I'm using a Nordic BLE nRF8001 development kit for testing CoreBluetooth. Using CBCentralManager's methods(e.g. didDiscoverPeripheral(), didConnectPeripheral(), etc.) my iPhone 5 is able to detect the Nordic device's advertisements and connect to it just fine. However, I'm not receiving any response from the new locationManager ranging or regionMonitoring methods. Below I'll explain my setup:

1.) First I retrieved my NSUUID from my Nordic device in the didDiscoverPeripheral() delegate method using the passed in peripheral device (my Nordic device). I created a custom service for my Nordic device among other things, so assume this peripheral is the Nordic device. To retrieve the NSUUID I used:

    NSUUID *uuid = [peripheral identifier];  
    NSString *uuidString = [uuid UUIDString]; //uuidString = 9A8D4C73-152D-BBDA-E4C2-9CE952654645

2.) Next I create a beacon region for my Nordic device and create a CLLocationManager:

    self.locationManagerBeacon = [[CLLocationManager alloc] init];
    [self.locationManagerBeacon setDelegate:self];
    NSUUID *myUUID = [[NSUUID alloc] initWithUUIDString:@"9A8D4C73-152D-BBDA-E4C2-9CE952654645"];
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:myUUID
                                                      identifier:@"nordicRegion"];
    self.beaconRegion.notifyEntryStateOnDisplay = YES;

3.) Now I start monitoring for the beacon region

[self.locationManagerBeacon startRangingBeaconsInRegion:self.beaconRegion];

4.) Problem: locationManager:didRangeBeacons:inRegion gets invoked, but the beacons region is always empty.

Question: Does the Nordic BLE device need to be configured in a certain manner such that the new locationManager beacon methods will detect it (e.g. BLE advertisement frequency, power level, etc.)? If so, could someone point me to the documentation.

Appreciate the help!

回答1:

I've always assumed that in order to use beacon ranging you have to first start beacon monitoring:

[theLocManager startMonitoringForRegion: region1];
[theLocManager startRangingBeaconsInRegion: region1];

That code works just fine for me (plus, like you, I also set notifyEntryStateOnDisplay = YES).

Try that and see if it makes a difference. Failing that, I'd say you have something wrong in the BLE packet you are broadcasting to serve as a beacon advertisement.

You might also try downloading Apple's AirLocate demo (which will both listen for beacons and turn your iOS device into a beacon.) You could use AirLocate to see if it recognizes your custom BLE device as a beacon. If it does, then use AirLocate to transmit as a beacon and see if your code recognizes it.



回答2:

I found that sometimes having an empty string (@"") as an identifier will cause the same pro

region = [[CLBeaconRegion alloc] initWithProximityUUID:UUID identifier:[UUID UUIDString]];

Hopefully that helps

Z.



回答3:

Thanks to Duncan for commenting about "something wrong in the BLE packet". I was using some Estimote beacons I bought a while ago. I was also getting back an empty array. When I connected to them with the Estimote iOS app, it showed that the Estimote Operating System was out of date. I used the app to update the beacons and they started showing up for me in the array.



回答4:

In my experience, there are a few things that may go wrong if you have followed Duncan's instructions and it still doesn't work:

  • The CLBeaconRegion that you create needs to have unique identifiers if you are monitoring multiple regions. If they are not unique, then didRangeBeacons will be called will empty array beacons.
  • You shouldn't call startMonitoringForRegion and startRangingBeaconsInRegion in a dispatch_async block.
  • If it still fails, check in your implementation of centralManagerDidUpdateState that you reset the monitoring when you see CBCentralManagerStatePoweredOn.