How to scan multiple regions using startMonitoringForRegion in Objective-C
Asked Answered
C

3

4

I've been through two tutorials and am reading up on basic C. Learn best through doing and have written a few light apps in the past week or so. Am getting up to speed to write some apps that will use ibeacon. As I'm going through some samples and reading the reference guide I see that multiple regions can be scanned by running startMonitoringForRegion for each UUID. OK, so I figure I could just run it for each UUID but that's not working. I'm sure I'm doing something basic totally wrong... the code below is a total hack - once I get the semantics I will pull the UUIDs from a DB with an API call and than loop through them to activate the monitoring. The code below results in last loop only showing two of the four UUIDs.

in header:

@property (strong, nonatomic) CLBeaconRegion *myBeaconRegion;
@property (strong, nonatomic) CLBeaconRegion *myBeaconRegion2;
@property (strong, nonatomic) CLBeaconRegion *myBeaconRegion3;
@property (strong, nonatomic) CLBeaconRegion *myBeaconRegion4;

in main:

NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"86E4BDEA-C6FF-442C-95CB-E6E557A23CF2"];
self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"com.appcoda.testregion"];

NSUUID *uuid2 = [[NSUUID alloc] initWithUUIDString:@"C9AFF296-A722-4F2D-8669-47B7CCC79A14"];
self.myBeaconRegion2 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid2 identifier:@"com.appcoda.testregion"];

NSUUID *uuid3 = [[NSUUID alloc] initWithUUIDString:@"1DBDDC7C-49BB-48BF-A2F6-A4825BD514EA"];
self.myBeaconRegion3 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid3 identifier:@"com.appcoda.testregion"];

NSUUID *uuid4 = [[NSUUID alloc] initWithUUIDString:@"8D942B9E-0197-4C81-8722-92144599E9F7"];
self.myBeaconRegion4 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid4 identifier:@"com.appcoda.testregion"];

[self.locationManager startMonitoringForRegion:self.myBeaconRegion];
[self.locationManager startMonitoringForRegion:self.myBeaconRegion2];
[self.locationManager startMonitoringForRegion:self.myBeaconRegion3];
[self.locationManager startMonitoringForRegion:self.myBeaconRegion4];

NSSet *setOfRegions = [self.locationManager monitoredRegions];
    for (CLRegion *region in setOfRegions) {
        NSLog (@"region info: %@", region);
    }
Chicory answered 15/1, 2014 at 5:56 Comment(0)
B
11

I think the problem is your region identifiers. Each beacon region identifier must be unique, otherwise CLLocationManager treats them as the same region.

Try setting a unique identifier for each region:

NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"86E4BDEA-C6FF-442C-95CB-E6E557A23CF2"];
self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"com.appcoda.testregion"];

NSUUID *uuid2 = [[NSUUID alloc] initWithUUIDString:@"C9AFF296-A722-4F2D-8669-47B7CCC79A14"];
self.myBeaconRegion2 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid2 identifier:@"com.appcoda.testregion2"];

NSUUID *uuid3 = [[NSUUID alloc] initWithUUIDString:@"1DBDDC7C-49BB-48BF-A2F6-A4825BD514EA"];
self.myBeaconRegion3 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid3 identifier:@"com.appcoda.testregion3"];

NSUUID *uuid4 = [[NSUUID alloc] initWithUUIDString:@"8D942B9E-0197-4C81-8722-92144599E9F7"];
self.myBeaconRegion4 = [[CLBeaconRegion alloc] initWithProximityUUID:uuid4 identifier:@"com.appcoda.testregion4"];

You should see each region listed from your NSLog statement. No need for dispatch_async, either.

Blanc answered 16/1, 2014 at 23:0 Comment(2)
I can not work on my iphone5s with os 7.1.1. but it used to work well for one beacon region. Anyone can work well by this way ?Ulna
Amazing! The reason is because of same region name. Thanks a lot!! :)Robb
F
0

The header file for startMonitoringForRegion states "This is done asynchronously and may not be immediately reflected in monitoredRegions".

You can verify this by adding a time delay to your for loop:

double delayInSeconds = 5.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    NSSet *setOfRegions = [self.locationManager monitoredRegions];
    for (CLRegion *region in setOfRegions) {
        NSLog (@"region info: %@", region);
    }
});
Flamsteed answered 15/1, 2014 at 8:11 Comment(2)
No luck. So I added that piece of code and it does delay. I also increased the delay and had pretty much the same result. Couple of odd things though. Once of the UUIDs is not one I have in the code... and I started to comment out the UUID from the bottom up to see it's only the last one being displayed... and that is what it looks like. Could I be adding to the startMonitoringForRegion incorrectly?Chicory
Pretty sure you've added to startMonitoringForRegion correctly, but the time delay does exist. You can add a UIButton which loops through the monitoredRegions and print out the UUIDs when tapped - you'll notice that different UUIDs are being printed each time. Eventually you should see all your added UUIDs there.Flamsteed
W
0

If you need to use multiple beacons to be monitored then you can able to differentiate using the beacon Major and Minor values. Read the tutorial here to understand about the ibeacons better.

-(void)setBeaconTranmitter:(NSInteger)major minorValue:(NSInteger)minor {
    // We need to set beacon regions here.
    NSUUID * uid = [[NSUUID alloc] initWithUUIDString:uuid]; //uuid value is static common string for all beacons.
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uid major:major minor:minor identifier:beaconsId];//beaconsId is a common identifier for all beacons.
    
// Call your Transmitter function here
    [self configureTransmitter];
}

Above way I have configured three beacons regions with major and minor value difference. I placed three buttons and called IBAction to send different Major and Minor values using tags and calling function. I installed the same app in three different iphones and enabled each different button in each phones and installed a receiver in another phone for demo. Worked like charm! but it takes time to detect region while moving from one region to another.

Wieland answered 10/12, 2014 at 18:34 Comment(2)
This is a borderline link-only answer. You should expand your answer to include as much information here, and use the link only for reference.Pelage
Sure, I will include this in my future response. ThanksWieland

© 2022 - 2025 — McMap. All rights reserved.