如何使用 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 获取最近的位置

如何使用 CoreLocation 框架而不是谷歌地图 API 获取任何给定地址的坐标?

如何轮询 CoreLocation 而不是获取更新?

CoreLocation 从坐标获取一定距离和方向的经纬度

您如何发现用户正在使用带有缓冲区的 CoreLocation 的美国州?

CoreLocation 负值