首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在立即监控BeaconRegion方面还有其他解决方案吗?

在立即监控BeaconRegion方面还有其他解决方案吗?
EN

Stack Overflow用户
提问于 2021-09-28 01:07:31
回答 1查看 76关注 0票数 0

我用iBeacon做了一个应用程序。

我决定使用CoreLocation和测距。

但是,我认为测距会消耗太多的能量。

作为测距的另一种选择,我尝试使用监控。

然后,介绍了测距的使用能量水平和监控的使用能量水平。

测距比监测高出两个能源使用水平

结果:(测距级别: 10/20,监测级别: 8/20)

但是,监控并没有立即调用didExit或didDetermineState 。

我要我的应用程序有一个实时测距。

我的解决方案:

  1. 监控启动
  2. 如果我进入监视区域,我就开始测距
  3. 如果退出区域,则测距结果为零,并停止测距。
  4. 监控停止和启动。

监视不会立即调用exit或determineState方法。

但是,我发现停止并重新运行监视使我的应用程序具有实时性。

我认为这个解决方案可以减少待机时的能源消耗。

而且它真的很管用!

这是我的密码。

代码语言:javascript
复制
class Service: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate, CLLocationManagerDelegate{
    private let constraint = CLBeaconIdentityConstraint(uuid: Constants.beaconUUID!,
                                                        major: Constants.beaconMajor,
                                                        minor: Constants.beaconMinor)
    
    private let region = CLBeaconRegion(beaconIdentityConstraint:
                                            CLBeaconIdentityConstraint(uuid: Constants.beaconUUID!,
                                                                       major: Constants.beaconMajor,
                                                                       minor: Constants.beaconMinor),
                                        identifier: Constants.beaconIdentifier)

    
    var locationManager: CLLocationManager!

    override init() {
        super.init()
        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.requestAlwaysAuthorization()
    }
}

extension Service {
    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
        if manager.authorizationStatus == .authorizedAlways {
            region.notifyOnExit = true
            region.notifyOnEntry = true
            region.notifyEntryStateOnDisplay = true
            
            manager.startMonitoring(for: region)
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
        if state == .inside {
            didEnterEvents(manager)
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didRange beacons: [CLBeacon], satisfying beaconConstraint: CLBeaconIdentityConstraint) {
        if beacons.first == nil {
            didExitEvents(manager)
            stopAndRerunMonitoring(manager, for: region)
        }
    }
}

extension Service {
    private func stopAndRerunMonitoring(_ manager: CLLocationManager, for region: CLRegion) {
        print("reboot!")
        manager.stopMonitoring(for: region)
        manager.startMonitoring(for: region)
    }
    
    private func didEnterEvents(_ manager: CLLocationManager) {
        print("inside")
        manager.startRangingBeacons(satisfying: constraint)
    }
    
    private func didExitEvents(_ manager: CLLocationManager) {
        print("outside")
        manager.stopRangingBeacons(satisfying: constraint)
    }
}

我知道我的解决方案很糟糕。

但我找不到其他解决办法了。

拜托,你能找到其他更好的解决办法吗?

等等:

  1. didEnter和didExit称为determineState方法。 我需要在其他代码中调用requestState()方法。因此,我在方法中编写了一个输入事件逻辑
  2. 你需要实时的? 是的,因为我会用信标制造安全系统。所以我的应用程序的要求是实时的。我需要实时区域和更少的能源消耗。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-28 03:31:38

您描述的从区域进入范围开始并在区域出口处停止它的方法并不“可怕”。事实上,这是相当普遍的。它经常被用来确定所检测到的信标的确切标识符,否则单靠监测是不可能的。

对于您的用例,在区域内进行测距也会加快区域退出事件,因为它强制进行持续的蓝牙扫描,而不是依赖用于监视的较慢的硬件过滤器。当测距处于活动状态时,区域出口会在最后一次探测到信标后30秒出现。

要使这是一个实用的解决方案,您必须考虑到背景行为:

  1. 除非你做一些特别的技巧,否则当屏幕关闭时,iOS不会让你的范围超过几秒钟。一旦测距停止,您将失去快速区域出口。
  2. 当屏幕开着的时候,不用一直测距就能节省电池是没有意义的,因为照明屏幕使用的电量是持续蓝牙测距扫描量的100倍以上。

为了从您描述的技术中获得任何好处,您必须像我的博客文章这里所描述的那样,在后台扩展测距时间。请注意,自从我写了那篇文章以来,Apple已经将你可以在后台扩展的时间从180秒缩短到30秒,这可能不足以满足您的需要。您可以通过以下方式获得无限的背景信息:

  1. 将位置背景模式添加到Info.plist
  2. 从用户获取“始终”位置权限。仅仅获得“使用中”许可是不够的。
  3. 启动后台任务,如下所述:http://www.davidgyoungtech.com/2014/11/13/extending-background-ranging-on-ios
  4. 从CoreLocation请求3公里的位置更新。这将保持应用程序在没有额外的电池从全球定位系统流失的背景下运行,因为3公里的精度只使用电池收音机,你不需要做任何事情对这些结果。你只需要请求他们保持应用程序的活力。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69354677

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档