为此,您需要保持 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 集已更新。