如何在单个didRangeBeacons:inRegion回调中接收ibeacons不同区域测距事件. [英] How to received ibeacons different regions ranging event in single didRangeBeacons:inRegion callback.
问题描述
我正在尝试将iOS ibeacons分布在多个区域,并且效果很好.
I'm trying to range iOS ibeacons with multiple regions and it works well.
但是我的问题是,如果我对多个区域region1
和region2
进行测距,则分别收到两个测距事件调用,即didRangeBeacons:inRegion
. (因此,如果我在表视图中显示信标列表,它会闪烁.)
But my problem is, if I range multiple regions region1
and region2
, I received two ranging event calls, didRangeBeacons:inRegion
separately. (So, if I show the beacons list in tableview, it is flashing.)
我想将范围内具有不同标识符的所有区域都接收到单个didRangeBeacons:inRegion
回调中(一个区域没有一个回调.范围内所有区域一个回调).我看到可以通过设置estBeaconManager.returnAllRangedBeaconsAtOnce = YES;
来使用Estimote的SDK.
I want to received all regions with different identifier in ranges into single didRangeBeacons:inRegion
callback (not one callback for one region. one callback for all regions in range). I saw it can be done with Estimote's SDK by setting estBeaconManager.returnAllRangedBeaconsAtOnce = YES;
.
我想实现类似的解决方案,例如estimote sdk对iOS CoreLocation
所做的事情.有没有解决方案或示例代码?
I want to implement similar solution like estimote sdk did with iOS CoreLocation
. Is there any solutions or sample code for this?
推荐答案
为此,您需要保持CLBeacon对象的NSDictionary,并在每次调用didRangeBeacons方法时使其保持同步.
To do this you will need to keep an NSDictionary of CLBeacon objects and keep it synchronized each time the didRangeBeacons method is called.
重要的是要理解,每次调用didRangeBeacons方法时,都会生成并返回一组新的CLBeacon对象,这些对象不是以前返回的CLBeacons的==.为了解决这个问题,我建议将您的CLBeacon存储在具有唯一ID的NSMutableDictionary中,该ID可用于识别和比较代表相同实际iBeacon的多个CLBeacon实例.这样,您可以轻松地从NSDictionary添加/删除CLBeacons并保持最新状态,并且每次调用didRangeBeacons之后都不会重复.
It is important to understand that you each time the didRangeBeacons method is called, a new set of CLBeacon objects generated and returned that are not == to the previously returned CLBeacons. To handle this I would recommend storing your CLBeacons in an NSMutableDictionary with a unique ID that can be used to identify and compare multiple instances of CLBeacon that represent the same actual iBeacon. This way you can easily add/remove CLBeacons from the NSDictionary and keep it up to date, and with no duplicates after each time the didRangeBeacons is called.
这是操作方法:
首先在您的CLLocationManager的委托中创建字典
First create the dictionary in your CLLocationManager's delegate
@property (nonatomic, strong) NSMutableDictionary *beaconsByUniqueID;
接下来修改您的didRangeBeacons方法,将每组新的CLBeacon对象合并到
Next modify your didRangeBeacons method to merge each new set of CLBeacon objects into
- (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创建一个唯一值.
Your uniqueIDForBeacon method can return any NSString that will be unique to the iBeacon. I would recommend simply combining the UUID, major, and minor values into one string to create a unique value for each iBeacon.
- (NSString *)uniqueIDForBeacon:(CLBeacon *)beacon {
return [NSString stringWithFormat:@"%@%@%@", [beacon.proximityUUID UUIDString], beacon.major, beacon.minor];
}
您说过,您想要一个回调来返回所有iBeacons.您可以简单地创建一个自定义MYiBeaconManager对象,该对象实现上述代码,并在didRangeBeacons末尾调用对其委托的自定义调用,以告知委托人iBeacon集已更新.
You said that you want a single callback to do return all iBeacons. You could simply create a custom MYiBeaconManager object that implements the above code and calls a custom call to its delegate at the end of didRangeBeacons to tell the delegate that the iBeacon set was updated.
这篇关于如何在单个didRangeBeacons:inRegion回调中接收ibeacons不同区域测距事件.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!