Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
382 views
in Technique[技术] by (71.8m points)

iphone - iBeacon: get major and minor - only looking for uuid

I'm using the air locate example and monitoring for iBeacons by uuid only. When I get the entered region event, I can't seem to get the major and minor from the beacon/region that has triggered the event if I'm only looking for the uuid (I can if I'm monitoring for a uuid with specified major and minor) - does anyone know a way to do this/am I missing something?

I don't really want to start ranging - doesn't seem like I should need to..

(The use case is for say lots of stores all with beacons with the same uuid, then issuing an OS notification with relevant information about that store (obtained by querying the major and minor))

Here's basically what I do:

CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
identifier:@"blah"];
region.notifyOnEntry = YES;
region.notifyOnExit = YES;
region.notifyEntryStateOnDisplay = YES;

[self.locationManager startMonitoringForRegion:region];

Then in the app delegate:

- (void) locationManager:(CLocationManager*)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion*)region {

    // assume for now its the iBeacon
    CLBeaconRegion *beaconRegion = (CLBeaconRegion*) region;

    beaconRegion.major  // hasn't been set...

}

Many Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...