如何使用 CoreLocation 获取多个 iBeacon?
Posted
技术标签:
【中文标题】如何使用 CoreLocation 获取多个 iBeacon?【英文标题】:How do I use CoreLocation to get multiple iBeacons? 【发布时间】:2014-04-04 13:44:08 【问题描述】:我正在尝试使用 CoreLocation 来获取我的 ios 应用程序指定的多个 iBeacons - 我的想法是,如果它们在范围内,它会在找到它们时通知我。
问题是在 didEnterRegion 和 didExitRegion 方法中,我必须提供一个 CLBeaconRegion 对象。每个 iBeacon 都有一个,如果我只使用一个 iBeacon,我可以只使用那个,但由于有多个,我需要知道如何从这些方法中找到每个 CLBeaconRegion。
也许我误解了它的工作原理;如果有,请告诉我。
- (void)getForUUUIDs:(CDVInvokedUrlCommand *)command
//Get an array of UUID's to filter by
self->locationUUIDs = [self getArgsObject:command.arguments];
self->locationManager = [[CLLocationManager alloc] init];
self->locationManager.delegate = self;
scanCallback = command.callbackId;
for(NSInteger i = 0; i < [locationUUIDs count]; i++)
NSString *identifier = [NSString stringWithFormat:@"BLERegion %d",i];
CLBeaconRegion *thisRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[locationUUIDs allKeys] objectAtIndex:i] identifier:identifier];
[self->locationManager startMonitoringForRegion:thisRegion];
- (void)locationManager:(CLLocationManager*)manager didEnterRegion:(CLRegion*)region
[self->locationManager startRangingBeaconsInRegion:????];
-(void)locationManager:(CLLocationManager*)manager didExitRegion:(CLRegion*)region
[self->locationManager stopRangingBeaconsInRegion:????];
【问题讨论】:
您真的需要多个 UUID 吗?使用 Major/Minor 演奏会很多轻松。 你误会了。我们的客户会将他们使用的 UUID 输入到我们的系统中,应用程序将报告设备可以检测到哪些 UUID。我目前对位置不感兴趣,我只是收集信息并将其发送回去。我什至不知道他们会使用什么 iBeacon。 【参考方案1】:在触发监视器进入/退出事件的同一区域上进行测距非常简单:
- (void)locationManager:(CLLocationManager*)manager didEnterRegion:(CLRegion*)region
[self->locationManager startRangingBeaconsInRegion:(CLBeaconRegion *)region];
这将在您开始监控时使用的完全相同的区域开始测距。请注意,有一个区域参数传递给回调。该 Region 参数将包含您之前设置的相同 UUID。
还有一点:虽然在进入区域时开始测距并在退出区域时停止测距并没有错,但实际上没有必要这样做。在您开始监测的同时开始测距。因为当 iBeacon 不可见时测距不会做任何事情,最终结果将几乎相同。唯一的区别是,如果您提前设置,您可能会提前一秒钟获得第一个测距回调。不会额外消耗电池或系统资源。
提前设置它的额外好处是您不必进行 CLRegion 对象的转换——您可以从原始对象开始。而且您不必实现监控回调方法,因此您的代码更简单。像这样:
- (void)getForUUUIDs:(CDVInvokedUrlCommand *)command
//Get an array of UUID's to filter by
self->locationUUIDs = [self getArgsObject:command.arguments];
self->locationManager = [[CLLocationManager alloc] init];
self->locationManager.delegate = self;
scanCallback = command.callbackId;
for(NSInteger i = 0; i < [locationUUIDs count]; i++)
NSString *identifier = [NSString stringWithFormat:@"BLERegion %d",i];
CLBeaconRegion *thisRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[locationUUIDs allKeys] objectAtIndex:i] identifier:identifier];
[self->locationManager startMonitoringForRegion:thisRegion];
[self->locationManager startRangingBeaconsInRegion:thisRegion];
【讨论】:
这是我的第一个想法,但我得到的是 CLRegion 类型,而不是 CLBeaconRegion,并且这些方法需要 CLBeaconRegion。 哦,对了。简单的修复:只需投射它。我已经编辑了我的答案以显示这一点。 你就像 iBeacons 之神。非常感谢,显然我对 Objective-C 的初步理解让我失望了(或者可能是缺乏想象力)。 @davidgyoung 我读到了一些***.com/questions/20834211/…,一个应用程序一次最多可以监控20个区域,所以在上述情况下,如果locationUUIDs
超过应用程序可以正常工作吗?
与有 20 个区域限制的监控不同,您可以根据需要设置任意数量的信标区域——没有限制。也就是说,如果监控区域用完,上面的 first 代码块可以工作,因为您永远不会收到超过 20 个区域的入口回调。上面的第二个代码块将工作以开始测距甚至超过 20 个地区。【参考方案2】:
您的区域由 uuid 指定
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
identifier:identifier];
您的所有信标都必须共享该 uuid。因此,当您确定信标的范围时,您可以通过该方法 (CLLocationManagerDelegate) 获取它们。
-(void)locationManager:(CLLocationManager*)manager didRangeBeacons:(NSArray*)beacons inRegion:(CLBeaconRegion*)region
for (CLBeacon *beacon in beacons)
NSLog(@"Major : %@", beacon.major);
NSLog(@"Minor : %@", beacon.minor);
主要和次要属性用于区分您的信标。
【讨论】:
但是我有多个正在使用的 UUID。所以我围绕它们进行迭代并指定区域。但由于它的异步性,我不知道哪个 CLRegion(当它返回一个区域时)符合每个 CLBeaconRegion(我从它开始)。 我在上面的答案中写了一个简短的解释。 我明白你的意思,但我不知道要获取数组的哪个元素,因为我不知道它正在进入/退出哪个区域。我想最好的异步性。以上是关于如何使用 CoreLocation 获取多个 iBeacon?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 CoreLocation 框架而不是谷歌地图 API 获取任何给定地址的坐标?