如何听取信标并获得最接近的信标

时间:2014-12-08 14:27:06

标签: ios ibeacon

我想听取信标并获得最接近的信标。我现在可以获得UUID但是我在获取其他数据时遇到了很多麻烦。所有google搜索,github搜索和堆栈溢出搜索都显示当你已经拥有UUID时获取此信息(换句话说,当你从get get获得UUID时)。我甚至尝试了苹果示例代码,它甚至找不到我的灯塔。 (RFduino,那里有应用程序虽然看到它"粒子检测器"是其中之一,所以我知道它可以完成。)

以下代码显示了当用户走动时我是如何从灯塔获取uuid的。虽然我可以只运行UUID但它也不会给我哪一个最接近它。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;

    if ([_locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        NSLog(@"requestAlwaysAuthorization!!!");
        [_locationManager requestAlwaysAuthorization];
    }

    AIBBeaconRegionAny *beaconRegionAny = [[AIBBeaconRegionAny alloc] initWithIdentifier:@"Any"];
    [self.locationManager startRangingBeaconsInRegion:beaconRegionAny];

    return YES;
}

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    NSLog(@"locationManagerDidChangeAuthorizationStatus: %d", status);
}

- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
    //NSLog(@"locationManager:%@ didRangeBeacons:%@ inRegion:%@",manager, beacons, region);
          {
              CLBeacon *beacon = [beacons firstObject];
              NSLog(@"Proximity UUID: [%@]", beacon.proximityUUID.UUIDString);

              [[NSNotificationCenter defaultCenter] postNotificationName:@"BeaconFound" object:beacon.proximityUUID.UUIDString];
          }
}

- (void)locationManager:(CLLocationManager *)manager rangingBeaconsDidFailForRegion:(CLBeaconRegion *)region withError:(NSError *)error
{
    NSLog(@"locationManager:%@ rangingBeaconsDidFailForRegion:%@ withError:%@", manager, region, error);

}

我基本上想知道最近的UUID是什么,所以我可以把它传递给数据库调用并且卡住了。

3 个答案:

答案 0 :(得分:2)

这里有三个问题:

  1. 除非您事先知道信标的ProximityUUID,否则您无法在iOS(或使用任何其他API)上使用CoreLocation API读取iBeacon标识符。这是Apple实施的安全限制,在Android,OSX或Linux等其他平台上不存在。即使您尝试使用CoreBluetooth读取原始蓝牙数据包,也无法执行此操作,因为iOS会从iBeacon传输的广告中过滤掉原始广告数据。您可以在此处详细了解:http://developer.radiusnetworks.com/2013/10/21/corebluetooth-doesnt-let-you-see-ibeacons.html

  2. 要读取信标标识符,您需要使用CoreLocation范围API,您可以在示例中执行此操作。但您需要先设置一个CLBeaconRegion过滤器,该过滤器会说明哪些信标标识符(例如哪个ProximityUUID)与您的过滤器匹配。您的代码引用了一个名为AIBBeaconRegionAny的类,但它没有显示它是如何设置的,或者它正在查找的ProximityUUID。如果此CLBeaconRegion过滤器与您的传输信号不匹配,则您不会在回调中获取信标。

  3. 一旦检测到信标,为了查看最接近的信标,您需要遍历beacons数组中的locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region数组 accuracy回调,并比较每个信标的accuracy属性。具有最低{{1}}值的信标是最接近的。

  4. 做#3时要小心,因为每个样本的信标距离估计值会有很大差异。您可能会看到估计的最近信标随时间来回切换。

答案 1 :(得分:1)

-locationManager:didRangeBeacons:inRegion:方法中,您只查看数组中的第一个信标:

CLBeacon *beacon = [beacons firstObject];

,您甚至没有查看proximityaccuracy属性。相反,您应该根据信标的接近度或准确度(根据您的需要)对数组进行排序,并使用结果来确定最接近的信标。

答案 2 :(得分:1)

为了获得最接近的信标,请执行以下操作:

- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
  CLBeacon *closest = nil;
  for (CLBeacon *beacon in beacons) {
    if (closest == nil || closest.accuracy > beacon.accuracy) {
      closest = beacon;
    }
  }
  NSLog(@"The closest beacon is %@", beacon);
}