我用iBeacon做了一个应用程序。
我决定使用CoreLocation和测距。
但是,我认为测距会消耗太多的能量。
作为测距的另一种选择,我尝试使用监控。
然后,介绍了测距的使用能量水平和监控的使用能量水平。
测距比监测高出两个能源使用水平
结果:(测距级别: 10/20,监测级别: 8/20)
但是,监控并没有立即调用didExit或didDetermineState 。
我要我的应用程序有一个实时测距。
我的解决方案:
监视不会立即调用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)
}
}我知道我的解决方案很糟糕。
但我找不到其他解决办法了。
拜托,你能找到其他更好的解决办法吗?
等等:
发布于 2021-09-28 03:31:38
您描述的从区域进入范围开始并在区域出口处停止它的方法并不“可怕”。事实上,这是相当普遍的。它经常被用来确定所检测到的信标的确切标识符,否则单靠监测是不可能的。
对于您的用例,在区域内进行测距也会加快区域退出事件,因为它强制进行持续的蓝牙扫描,而不是依赖用于监视的较慢的硬件过滤器。当测距处于活动状态时,区域出口会在最后一次探测到信标后30秒出现。
要使这是一个实用的解决方案,您必须考虑到背景行为:
为了从您描述的技术中获得任何好处,您必须像我的博客文章这里所描述的那样,在后台扩展测距时间。请注意,自从我写了那篇文章以来,Apple已经将你可以在后台扩展的时间从180秒缩短到30秒,这可能不足以满足您的需要。您可以通过以下方式获得无限的背景信息:
https://stackoverflow.com/questions/69354677
复制相似问题