【问题标题】:Are there any other solutions in Monitoring BeaconRegion Immediately?立即监控 BeaconRegion 还有其他解决方案吗?
【发布时间】:2021-09-28 01:07:31
【问题描述】:

我用 iBeacon 做了一个应用程序。
我决定使用 CoreLocation 和 Ranging。
但是,我认为测距消耗了太多能量。

作为测距的替代方法,我尝试使用监控。
然后,我剖析 Ranging 的使用能级和 Monitoring 的使用能级。

测距比监控多使用大约 2 个能源使用水平
结果:(测距等级:10/20,监控等级:8/20)

但是,Monitoring 不会立即调用 didExit 或 didDetermineState。
我希望我的应用具有实时测距功能。


我的解决方案:

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

监控不会立即调用 exit 或 determineState 方法。
但是,我发现停止和重新运行监控使我的应用程序具有实时性。

我认为该解决方案可以减少待机时的能耗。
而且它确实有效!

▼ 这是我的代码。

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)
    }
}

我知道我的解决方案很糟糕。
但我找不到任何其他解决方案。
Lz,你能找到其他更好的解决方案吗?

等:

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

【问题讨论】:

    标签: ios swift core-location ibeacon


    【解决方案1】:

    您描述的在区域进入时开始测距并在区域退出时停止测距的方法并不“糟糕”。事实上,这很常见。它通常用于确定检测到的信标的确切标识符,否则仅靠监控是不可能的。

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

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

    1. 除非您采取特殊措施,否则 iOS 不会让您在屏幕关闭时超过几秒钟。一旦测距停止,您将失去快速区域出口。
    2. 屏幕打开时,不一直进行测距以节省电池电量是没有意义的,因为照明屏幕使用的电池电量是持续蓝牙扫描测距的 100 多倍。

    要从您描述的技术中获得任何好处,您必须在后台延长测距时间,如我的博客文章 here 中所述。请注意,自从我写那篇文章以来,Apple 已将您可以在后台扩展的时间从 180 秒减少到 30 秒,这可能不足以满足您的需求。您可以通过以下方式获得无限的背景范围:

    1. 在 Info.plist 中添加位置背景模式
    2. 从用户那里获得“总是”位置许可。仅获得“使用时”权限是不够的。
    3. 按照此处所述启动后台任务:http://www.davidgyoungtech.com/2014/11/13/extending-background-ranging-on-ios
    4. 向 CoreLocation 请求 3 公里位置更新。这将使应用程序在后台运行,而不会从 GPS 中消耗额外的电池电量,因为 3 公里精度仅使用蜂窝无线电您不需要对这些结果做任何事情。您只需要请求他们保持应用程序的运行即可。

    【讨论】:

    • 我对自己的解决方案充满信心!并感谢您对后台解决方案的建议!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 2012-04-28
    • 2017-04-27
    相关资源
    最近更新 更多