4

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

        }
}
user3626407
  • 287
  • 1
  • 6
  • 15
  • 5
    In `locationManager:didEnterRegion`, do `[yourLocationManager startRangingBeaconsInRegion:yourRegion];` and the delegate method is `locationManager:didRangeBeacons:inRegion:`. – Larme Sep 18 '14 at 08:41

5 Answers5

6

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.

davidgyoung
  • 63,876
  • 14
  • 121
  • 204
2

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

Bernd
  • 11,133
  • 11
  • 65
  • 98
0

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.

ntsh
  • 759
  • 5
  • 19
  • this will work, but be mindful that iOS limits each app sandbox to 20 regions max. If you initialize your beacon region with the major and minor, you'll be maxing out on the number of beacons you can use pretty quickly. If you initialize your beacon region with just the UUID, then you can have access to more than 20 beacons (e.g. each region contains more than one beacon). – kevinl Jul 01 '15 at 23:16
0

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

}
alper_k
  • 512
  • 1
  • 6
  • 18
0

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)

user1872384
  • 6,886
  • 11
  • 61
  • 103