Ios iBeacon后台监控和测距

Ios iBeacon后台监控和测距,ios,core-location,ibeacon,Ios,Core Location,Ibeacon,我花了几个月的时间开发一个基于iBeacons的应用程序,我真的很沮丧 一般的想法是,当检测到信标时,会向用户通知特定于该iBeacon的信息 该应用程序的设计如下,所有iBeacon都具有相同的UUID,主要决定建筑(博物馆、商店…),次要决定特定产品(图片、鞋子…)。因此,此应用程序可以服务于多个客户端 当应用程序启动时,我开始使用UUID对区域进行监视和测距。当应用程序在前台时,所有的工作都很完美。但在后台或挂起状态下,问题开始出现。不允许在后台或挂起状态下进行测距 我知道,当你进入或退出

我花了几个月的时间开发一个基于iBeacons的应用程序,我真的很沮丧

一般的想法是,当检测到信标时,会向用户通知特定于该iBeacon的信息

该应用程序的设计如下,所有iBeacon都具有相同的UUID,主要决定建筑(博物馆、商店…),次要决定特定产品(图片、鞋子…)。因此,此应用程序可以服务于多个客户端

当应用程序启动时,我开始使用UUID对区域进行监视和测距。当应用程序在前台时,所有的工作都很完美。但在后台或挂起状态下,问题开始出现。不允许在后台或挂起状态下进行测距

我知道,当你进入或退出信标区域时,该应用程序将在后台启动约5秒钟。你可以在这里进行5秒钟的后台扫描,之后iOS将再次暂停你的应用程序

我用在这里学到的技术在后台将测距范围延长了3分钟。我还得到一个额外的回调,notifyEntryStateondDisplay=YES

但这还不够,若客户端进入某个区域时应用程序处于后台或挂起状态,他将收到通知。在额外的3分钟内,如果测距检测到另一个iBeacon,他将收到通知,但当3分钟后台任务到期时,如果没有触发区域退出,他将不会再次收到任何通知

在这种情况下没有真正的解决方案吗?我认为这是一个非常常见的情况,我很惊讶没有办法处理它

编辑:我试图通过监测David Young在其回复中建议的两个区域来找到问题的解决方案。以获取更多的进入/退出区域的事件

我添加了我实现的代码,以尝试监视两个区域

但是我做得不正确,并且didRangeBeacons:InRegion:callback每10毫秒触发一次,而预期的是每秒一次

AppDelegate.m
中,我在
didfishlaunchingwithoptions中执行以下操作:

[self.locationManager startMonitoringForRegion:self.beaconRegion];
        [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
        [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
        [self.locationManager startMonitoringForRegion:self.beaconRegion2];
        [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion2];
        [self.locationManager startRangingBeaconsInRegion:self.beaconRegion2];

然后,在
didRangeBeacons:InRegion:

- (void) locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region{

     if(beacons.count > 0){
          [self.locationManager stopRangingBeaconsInRegion:region];
          for (CLBeacon *beacon in beacons){
             NSLog(@"beacon detected major: %@ minor: %@", beacon.major,beacon.minor);
          }
           [self.locationManager startRangingBeaconsInRegion:region];   
     }

}
当我在模拟器上运行应用程序时,范围内的每个网络都有一个信标,消息大约每10毫秒显示在控制台上


我怀疑停止并重新启动范围会破坏预期的回调流,但当范围内只有一个区域时,回调会按预期每秒发生一次。

您描述的问题很常见。除了延长背景测距时间(您已经这样做了),iOS上没有灵丹妙药

另外两种技巧可能会有所帮助。这两种技巧都涉及在从一个信标传递到下一个信标时获得新的进入事件:

  • 获取允许您调低发射机功率的硬件信标(我公司的RadBeacon产品允许这样做),以便传输不会重叠。这样,当您从一个信标移动到另一个信标时,您会得到一个退出事件,然后是一个新的进入事件

  • 重新设计您的标识符schene,以便主要字段专用于识别多达20个不同的区域(基于UUID和主要1-20)。然后监视所有这些区域。你的个人信标仍然可以使用次要的,但你想,特别是作为关键触发消息。在放置信标时,请确保所有具有重叠传输的信标都不共享同一个主频。这将确保在您从一个移动到另一个时出现新的背景输入事件


  • 背景中的信标测距在iOS 8上工作得很好,只要你能跳过所有的障碍

    首先,您需要正确的授权。将密钥
    NSLocationAlwaysUsageDescription
    添加到您的Info.plist,然后拨打

    [self.locationManager requestAlwaysAuthorization];
    
    您的应用程序必须具有
    位置更新的
    后台模式
    。在Info.plist中或通过功能指定(与生成设置并行)

    然后在
    applicationIDBECOMEACTIVE
    中使用

    switch([CLLocationManager authorizationStatus])
    {
        ...
    
    一旦获得授权,您需要执行以下操作:

    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    // If you don't do this, location updates will pause after 15 minutes in the same place
    // Usually this is what you want, so I've left this line commented out
    // self.locationManager.pausesLocationUpdatesAutomatically = NO;
    
    // Create a NSUUID with the same UUID as the broadcasting beacon
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:kProximityUUID];
    
    _beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
                                                      identifier:@"uk.co.airsource.testregion"];
    
    // Necessary to get continued background ranging.
    // See https://community.estimote.com/hc/en-us/articles/203914068-Is-it-possible-to-use-beacon-ranging-in-the-background-
    _locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
    [_locationManager startUpdatingLocation];
    [_locationManager startMonitoringForRegion:self.beaconRegion];
    

    你能给我更多关于第一种选择的信息吗?第二个是复杂的,因为Major标识了客户端,这将改变整个后端和android应用程序。如果我用相同的UUID定义一个虚拟网络,但有一个特定的Major和Minor,这是一个疯狂的想法。我开始监测和测量两个区域,一个只有UUID,第二个有UUID和特定的大调和小调。如果我分发虚拟的网络信标,将它们放置在可能有重叠的战略位置。我会得到额外的区域入口和出口?对于第一种选择,你只需让信标传输的距离更小,比如说10米。只要你的信标相距至少20米,当你在信标之间移动时,你就会得到进出事件。你在上面评论中的第二个建议是我回答中第二个选择的可行变体。您只需要部署额外的信标就可以实现这种变体。我正试图监视两个区域,但我发现了一些奇怪的情况。当我只监视一个区域时,“didRangeBeacons”回调每秒都会启动。但现在,当两个区域都在射程内时,它们大约每10毫秒发射一次。这是预期的行为?
    didRangeBeacons:InRegion:
    应该在1Hz的频率下为每个范围内的区域调用。即使有10个范围内的区域,您也只能每100毫秒收到一次调用。您确定在该回调方法的循环中没有看到这种计时吗?如果是这样,同时对100个可见信标进行测距可能会使回调次数减少,但每个信标的处理速率为每10毫秒一次。