4
votes

I'm trying to access the major and minor values for the closest beacon within the didEnterRegion delegate. However, when printing the values to the console they return null

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {

    if ([region isKindOfClass:[CLBeaconRegion class]]) {

        CLBeaconRegion *beaconRegion = (CLBeaconRegion *)region;

        int major = [beaconRegion.major intValue];
        int minor = [beaconRegion.minor intValue];

        NSLog(@" Major %@ Minor %@", beaconRegion.major, beaconRegion.minor);

        }
}
5
In locationManager:didEnterRegion, do [yourLocationManager startRangingBeaconsInRegion:yourRegion]; and the delegate method is locationManager:didRangeBeacons:inRegion:.Larme

5 Answers

6
votes

The region monitoring callback you have implemented will not tell you the individual identifiers of the beacons you detect. If you want to get the identifiers for individual beacons detected, you have to use the beacon ranging APIs as @Larme says in his comment. The callback for ranging includes a second parameter that is an array of all beacons seen.

2
votes

You have to differentiate between Monitoring and Ranging iBeacons. Only successfully ranging iBeacons provides you with the Major/Minor IDs.

0
votes

Looks like you are not initializing the BeaconRegion with minor and major values

While initializing the beacon region you need to use initWithProximityUUID:major:minor:identifier:

instead of

initWithProximityUUID:identifier:

If you do not want to initialize minor and major values into regions, then you may want to call didRangeBeacons method as mentioned in the comments.

0
votes

you're trying to get region's major and minor values. but you say that want to get the beacon's values.

it depends on which beacon brand you're using but there must be a method that returns the beacons array the device has found. generally the first object of the array is the closest one. in that method you can get the beacon's values.

an example code:

- (void)beaconManager:(ESTBeaconManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(ESTBeaconRegion *)region
{
    if([beacons count] > 0)
    {
        // beacon array is sorted based on distance
        // closest beacon is the first one
        ESTBeacon* closestBeacon = [beacons objectAtIndex:0];

        NSString* theMajor = [NSString stringWithFormat:@"%@",closestBeacon.major];
    }

}
0
votes

Setup locationManager (remember to configure plist for iOS 8 to add in these 2 values NSLocationAlwaysUsageDescription, NSLocationWhenInUseUsageDescription).

@property (strong, nonatomic) CLLocationManager *locationManager;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;

[[UIApplication sharedApplication] cancelAllLocalNotifications];

// Needed for iOS 8
if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
    [self.locationManager requestAlwaysAuthorization];
}

Then call startRangingItem:

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
    if ([region isKindOfClass:[CLBeaconRegion class]]) {

        [self startRangingItem];
    }
}


- (void)startRangingItem {
    CLBeaconRegion *beaconRegion = [self beaconRegionWithItem];
    [self.locationManager startRangingBeaconsInRegion:beaconRegion];
}

- (CLBeaconRegion *)beaconRegionWithItem{

    NSUUID *iPadTransmitterUUID = [[NSUUID alloc] initWithUUIDString:@"AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEFFFFF1"];

    CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:iPadTransmitterUUID identifier:@"Transmitter1"];

    return beaconRegion;
}

Then in didRangeBeacons:***

- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region{

    CLBeacon *testBeacon = [beacons objectAtIndex:0];

    NSLog(@"Inside didRangeBeacons Major %@ Minor %@", testBeacon.major, testBeacon.minor);

}

***Please note that this didRangeBeacons method will only run in background for 5 seconds once the user enter the region. It will stop ranging after 5 seconds. If you want to continue ranging, the user needs to launch the app. (forcing the didRangeBeacons to run in background is possible, but it might get rejected by apple)