You're not doing anything wrong. Surprising as it may seem, the monitoring API doesn't give you the specific beacon(s) that triggered the region change.
The reason the major isn't set on the CLBeaconRegion object is because that is the exact same object you used to start monitoring, and you set that field to nil (or didn't set it at all leaving it nil). What you are looking for is an additional array of CLBeacon objects. And as you suggest, this is only present on the Ranging APIs.
It really isn't a big deal to start ranging. Just set it up at the exact same time as you start monitoring:
CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
identifier:@"blah"];
region.notifyOnEntry = YES;
region.notifyOnExit = YES;
region.notifyEntryStateOnDisplay = YES;
[self.locationManager startMonitoringForRegion:region];
[self.locationManager startRangingBeaconsInRegion:region];
And if you only care about the first ranging call, you can use a flag to ignore further updates:
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
if (!_firstOneSeen) {
// Do something with beacons array here
}
}
And reset that flag when you leave the region
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
_firstOneSeen = NO;
}
As a bonus, this will also make your monitoring response times much faster when your app is in the foreground. See: http://developer.radiusnetworks.com/2013/11/13/ibeacon-monitoring-in-the-background-and-foreground.html
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…