Для этого вам необходимо сохранить NSDictionary объектов CLBeacon и синхронизировать их каждый раз, когда вызывается метод didRangeBeacons.
Важно понимать, что каждый раз, когда вызывается метод didRangeBeacons, генерируется и возвращается новый набор объектов CLBeacon, которые не являются == ранее возвращенными CLBeacons. Чтобы справиться с этим, я бы рекомендовал хранить ваши CLBeacons в NSMutableDictionary с уникальным идентификатором, который можно использовать для идентификации и сравнения нескольких экземпляров CLBeacon, которые представляют один и тот же фактический iBeacon. Таким образом, вы можете легко добавлять/удалять CLBeacons из NSDictionary и постоянно обновлять его, и без дубликатов после каждого раза вызывается 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 может возвращать любую NSString, которая будет уникальной для iBeacon. Я бы рекомендовал просто объединить UUID, основные и второстепенные значения в одну строку, чтобы создать уникальное значение для каждого iBeacon.
- (NSString *)uniqueIDForBeacon:(CLBeacon *)beacon {
return [NSString stringWithFormat:@"%@%@%@", [beacon.proximityUUID UUIDString], beacon.major, beacon.minor];
}
Вы сказали, что хотите, чтобы один обратный вызов возвращал все iBeacons. Вы можете просто создать пользовательский объект MYiBeaconManager, который реализует вышеуказанный код, и вызывает пользовательский вызов его делегату в конце didRangeBeacons, чтобы сообщить делегату, что набор iBeacon обновлен.
Единственный способ, которым я знаю, это объединить их в одну область, используя тот же самый proximityUUID. 'DidRangeBeacons: inRegion' делает только то, что он говорит, сообщает вам, какие маяки он задавал для * данного региона *. В противном случае вы можете написать свою собственную реализацию, которая в основном ждет, когда все обновления появятся для всех регионов и сразу же их вместе возвратят. – Mike