How to received ibeacons different regions ranging event in single didRangeBeacons:inRegion callback.

跟風遠走 提交于 2020-01-05 04:23:27

问题


I'm trying to range iOS ibeacons with multiple regions and it works well.

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.)

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;.

I want to implement similar solution like estimote sdk did with iOS CoreLocation. Is there any solutions or sample code for this?


回答1:


You simply need to combine the two arrays of visible beacons into a single list. You can do this by allocating an overall NSMutableDictionary in your AppDelegate's onCreate method, then add beacons to this dictionary (keyed by UUID/major/minor) in the ranging callback method.

The tricky part is removing the beacons from your combined list when they are no longer visible. The easiest way to do this is to keep a second NSMutableDictionary also keyed by UUID/major/minor, and storing an NSDate timestamp of when it was last seen. When a beacon's last seen timestamp is more than five seconds in the past, remove the beacon's entrust from each NSMutableDictionary.




回答2:


To do this you will need to keep an NSDictionary of CLBeacon objects and keep it synchronized each time the didRangeBeacons method is called.

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.

Here is how to do it:

First create the dictionary in your CLLocationManager's delegate

@property (nonatomic, strong) NSMutableDictionary *beaconsByUniqueID;

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
}

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];
}

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.



来源:https://stackoverflow.com/questions/26082459/how-to-received-ibeacons-different-regions-ranging-event-in-single-didrangebeaco

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!