1

我正在尝试将 iOS ibeacons 与多个区域一起使用,并且效果很好。

但我的问题是,如果我对多个区域进行测距,region1并且分别region2收到两个测距事件调用didRangeBeacons:inRegion。(所以,如果我在 tableview 中显示信标列表,它会闪烁。)

我想将范围内具有不同标识符的所有区域接收到单个didRangeBeacons:inRegion回调中(不是一个区域的一个回调。一个范围内的所有区域的回调)。我看到它可以通过设置 Estimote 的 SDK 来完成estBeaconManager.returnAllRangedBeaconsAtOnce = YES;

我想实现类似的解决方案,就像 estimote sdk 对 iOS 所做的那样CoreLocation。是否有任何解决方案或示例代码?

4

2 回答 2

0

为此,您需要保持 CLBeacon 对象的 NSDictionary 并在每次调用 didRangeBeacons 方法时保持同步。

重要的是要了解,每次调用 didRangeBeacons 方法时,都会生成并返回一组新的 CLBeacon 对象,这些对象与先前返回的 CLBeacon 不 ==。为了解决这个问题,我建议将您的 CLBeacon 存储在具有唯一 ID 的 NSMutableDictionary 中,该 ID 可用于识别和比较代表相同实际 iBeacon 的多个 CLBeacon 实例。这样,您可以轻松地从 NSDictionary 添加/删除 CLBeacons 并使其保持最新,并且每次调用 didRangeBeacons 后都不会重复。

这是如何做到的:

首先在您的 CLLocationManager 的委托中创建字典

@property (nonatomic, strong) NSMutableDictionary *beaconsByUniqueID;

接下来修改您的 didRangeBeacons 方法以将每组新的 CLBeacon 对象合并到

- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {

    if(!self.beaconsByUniqueID) {
        self.beaconsByUniqueID = [[NSMutableDictionary alloc] init]; // This could also be done in your init
    }

    // Remove all CLBeacon objects for the CLBeaconRegion being returned
    NSMutableArray *uniqueIDsToRemove = [[NSMutableArray alloc] initWithCapacity:[self.beaconsByUniqueID count]];
    for(NSString *beaconUniqueID in self.beaconsByUniqueID) {
        CLBeacon *beacon = [self.beaconsByUniqueID objectForKey:beaconUniqueID];
        if([beacon.proximityUUID isEqual:region.proximityUUID]) {     // Only remove Beacons in the currently returned region

            [uniqueIDsToRemove addObject:beaconUniqueID];
        }
    }
    [self.beaconsByUniqueID removeObjectsForKeys:uniqueIDsToRemove];

    // Add in the new beacon objects
    for(CLBeacon *beacon in beacons) {
        [self.beaconsByUniqueID setObject:beacon forKey:[self uniqueIDForBeacon:beacon]];
    }

    // beaconsByUniqueID now contains the most recent set of iBeacons with no duplicates
    // Reload your tableView here
    // or call a custom callback with beaconsByUniqueID
}

您的 uniqueIDForBeacon 方法可以返回任何对 iBeacon 唯一的 NSString。我建议简单地将 UUID、主要和次要值组合到一个字符串中,以便为每个 iBeacon 创建一个唯一值。

- (NSString *)uniqueIDForBeacon:(CLBeacon *)beacon {
    return [NSString stringWithFormat:@"%@%@%@", [beacon.proximityUUID UUIDString], beacon.major, beacon.minor];
}

你说你想要一个回调来返回所有 iBeacons。您可以简单地创建一个实现上述代码的自定义 MYiBeaconManager 对象,并在 didRangeBeacons 结束时调用其委托的自定义调用,以告知委托 iBeacon 集已更新。

于 2014-09-29T19:27:11.810 回答
0

您只需将两个可见信标数组组合成一个列表。NSMutableDictionary您可以通过在您AppDelegate的方法中分配一个整体来做到这一点onCreate,然后在测距回调方法中将信标添加到此字典(由 UUID/major/minor 键入)。

棘手的部分是当它们不再可见时从组合列表中删除信标。最简单的方法是保持一秒NSMutableDictionary也由 UUID/major/minor 键入,并存储NSDate最后一次看到的时间戳。当信标的最后一次看到时间戳超过五秒时,从每个 NSMutableDictionary.

于 2014-09-29T18:57:12.463 回答