How to get ibeacons of different regions starting an event in a single didRangeBeacons: inRegion callback.

I am trying to use iOS ibeacons with multiple regions and it works well.

But my problem is that if I have multiple scopes region1

and region2

, I get two event calls, didRangeBeacons:inRegion

separately. (So, if I show the list of beacons as a table, it blinks.)

I want to get all regions with different IDs in the ranges into one callback didRangeBeacons:inRegion

(not one callback for one region, but one callback for all regions in the range). I saw that it can be done with the Estimote SDK by installing estBeaconManager.returnAllRangedBeaconsAtOnce = YES;

.

I want to implement a similar solution, such assessment sdk with iOS CoreLocation

. Are there any solutions or code examples for this?

+1


source to share


2 answers


You just need to combine the two arrays of visible beacons into one list. You can do this by highlighting the general NSMutableDictionary

in your method AppDelegate

onCreate

, and then add beacons to that dictionary (with the key UUID / major / minor) in the range callback method.



The tricky part is removing the beacons from your combo box when they are no longer visible. The easiest way to do this is to store the second NSMutableDictionary

also with UUID / major / minor and keep the mark NSDate

when it was last seen. When last month the beacon's cue is more than five seconds, remove the beacon from each NSMutableDictionary

.

0


source


To do this, you need to store the NSDictionary of the CLBeacon objects and keep it in sync every time the didRangeBeacons method is called.

It is important to understand that each time the didRangeBeacons method is called, a new set of CLBeacons is generated and returned, which are not == for 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 CLBeacon instances that represent the same actual iBeacon. This way you can easily add / remove CLBeacons from NSDictionary and update it constantly and without duplicates after each call to doRangeBeacons.

Here's how to do it:

First create a dictionary in your CLLocationManager delegate

@property (nonatomic, strong) NSMutableDictionary *beaconsByUniqueID;

      



Next, modify the 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
}

      

Your uniqueIDForBeacon method can return any NSString that is unique to iBeacon. I would recommend just concatenating the UUIDs, 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];
}

      

You said you want one callback to return all iBeacons. You can simply create a custom MYiBeaconManager object that implements the above code and makes a special call to it to the delegate at the end of didRangeBeacons to tell the delegate that the iBeacon set has been updated.

0


source







All Articles