位置管理器 didExitRegion 未被调用
Location Manager didExitRegion not being called
我已经设置了委托,创建了一个区域,并且我已经阅读了所有文档。每次用户的位置发生变化并且在指定区域之外时,都不会调用 locationManager(manager: CLLocationManager, didExitRegion region: CLRegion)
。我见过它被调用一次然后就停止了。我花了很多时间试图弄清楚发生了什么。
快速了解我在做什么:
当应用程序启动时,我调用 locationManager.startUpdatingLocation()
,后者又调用委托 locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
,我向服务器快速请求一些我需要的信息,创建一个 CLCircularRegion
并继续呼叫 locationManager.stopUpdatingLocation()
。在那个方法中,我调用我的 startMonitoringForRegion(_:)
。
可能是因为我每次创建新区域时它都使用相同的标识符? Apple 的文档说使用相同的标识符是可以的,因为它将替换以前的标识符,但我想知道这是否会导致委托不调用 didExitRegion
。
我的代码如下。谢谢你。
func configureLocation() {
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.allowsBackgroundLocationUpdates = false
locationManager.pausesLocationUpdatesAutomatically = true
// Distance filter to update location
//locationManager.distanceFilter = 10.0
// Begin updating user location
locationManager.startUpdatingLocation()
} else {
let title = "Location disabled"
let message = "To enable location services go to Settings > Privacy > Location Services"
self.locationServicesAlertMessage(title, message: message)
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("didUpdateCalled")
/*
if UIApplication.sharedApplication().applicationState == .Active {
print("ACTIVE UPDATE: location")
} else if UIApplication.sharedApplication().applicationState == .Background {
print("BACKGROUND UPDATE: location")
}
*/
if firstLocationUpdate {
let center = CLLocationCoordinate2D(latitude: (manager.location?.coordinate.latitude)!, longitude: (manager.location?.coordinate.longitude)!)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpanMake(0.01, 0.01))
self.mapView.setRegion(region, animated: true)
self.firstLocationUpdate = false
}
// If the user is travelling less than 5 mph, update location
if manager.location?.speed <= 3.5 {
self.updateLongAndLat(manager.location!) { (lat, long) in
print("LAT: \(lat)")
print("LONG: \(long)")
if lat != nil && long != nil {
let center = CLLocationCoordinate2D(latitude: lat!, longitude: long!)
let monitoredRegion = CLCircularRegion(center: center, radius: 10.0, identifier: "UserRegion")
monitoredRegion.notifyOnEntry = false
self.locationManager.startMonitoringForRegion(monitoredRegion)
self.locationManager.stopUpdatingLocation()
}
}
}
}
func locationManager(manager: CLLocationManager, didExitRegion region: CLRegion) {
print("EXITED REGION")
print("Identifier: \(region.identifier)")
if manager.location?.speed <= 3.5 {
self.updateLongAndLat(manager.location!, completion: { (lat, long) in
if lat != nil && long != nil {
let center = CLLocationCoordinate2D(latitude: lat!, longitude: long!)
let monitoredRegion = CLCircularRegion(center: center, radius: 10.0, identifier: "UserRegion")
self.locationManager.startMonitoringForRegion(monitoredRegion)
}
})
}
}
区域监控不依赖GPS。它是小区 tower/wifi 接入点三角测量。您不应期望水平精度优于 65m。试图用 65 米精度的仪器检测 10 米的运动根本行不通。
我不知道iOS在被要求监视半径小于100m的区域时做了什么。充其量它只是将半径增加到 100。在这种情况下,您的应用程序仍然可以运行,但可能不是预期的方式。
要从评论中回答您的问题,恐怕 Apple 没有提供对其核心定位技术的深入见解。这就是开发人员之间存在很多困惑的原因,因为似乎没有任何东西能按预期工作。对于初学者来说,核心位置 API 旨在实施最佳实践以最大程度地减少电池消耗。
如果您想使用小于 ~300 米(是的,三百米)的定位服务,则必须使用 GPS。地理围栏无法跟上不断行走的用户的步伐。但是在后台持续使用 GPS 运行 是不对的,因为你会很快耗尽电池,你的应用程序很快就会被用户 phone 驱逐。
地理围栏不需要 GPS,但会很乐意使用可用的 GPS 数据(即使其他应用程序请求了 GPS 更新)。 GPS 辅助地理围栏的工作非常精确,但我看不出有什么好的理由同时使用这两种服务,因为只需将位置管理器过滤器设置为正确的距离就更简单了。
我已经设置了委托,创建了一个区域,并且我已经阅读了所有文档。每次用户的位置发生变化并且在指定区域之外时,都不会调用 locationManager(manager: CLLocationManager, didExitRegion region: CLRegion)
。我见过它被调用一次然后就停止了。我花了很多时间试图弄清楚发生了什么。
快速了解我在做什么:
当应用程序启动时,我调用 locationManager.startUpdatingLocation()
,后者又调用委托 locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
,我向服务器快速请求一些我需要的信息,创建一个 CLCircularRegion
并继续呼叫 locationManager.stopUpdatingLocation()
。在那个方法中,我调用我的 startMonitoringForRegion(_:)
。
可能是因为我每次创建新区域时它都使用相同的标识符? Apple 的文档说使用相同的标识符是可以的,因为它将替换以前的标识符,但我想知道这是否会导致委托不调用 didExitRegion
。
我的代码如下。谢谢你。
func configureLocation() {
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.allowsBackgroundLocationUpdates = false
locationManager.pausesLocationUpdatesAutomatically = true
// Distance filter to update location
//locationManager.distanceFilter = 10.0
// Begin updating user location
locationManager.startUpdatingLocation()
} else {
let title = "Location disabled"
let message = "To enable location services go to Settings > Privacy > Location Services"
self.locationServicesAlertMessage(title, message: message)
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("didUpdateCalled")
/*
if UIApplication.sharedApplication().applicationState == .Active {
print("ACTIVE UPDATE: location")
} else if UIApplication.sharedApplication().applicationState == .Background {
print("BACKGROUND UPDATE: location")
}
*/
if firstLocationUpdate {
let center = CLLocationCoordinate2D(latitude: (manager.location?.coordinate.latitude)!, longitude: (manager.location?.coordinate.longitude)!)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpanMake(0.01, 0.01))
self.mapView.setRegion(region, animated: true)
self.firstLocationUpdate = false
}
// If the user is travelling less than 5 mph, update location
if manager.location?.speed <= 3.5 {
self.updateLongAndLat(manager.location!) { (lat, long) in
print("LAT: \(lat)")
print("LONG: \(long)")
if lat != nil && long != nil {
let center = CLLocationCoordinate2D(latitude: lat!, longitude: long!)
let monitoredRegion = CLCircularRegion(center: center, radius: 10.0, identifier: "UserRegion")
monitoredRegion.notifyOnEntry = false
self.locationManager.startMonitoringForRegion(monitoredRegion)
self.locationManager.stopUpdatingLocation()
}
}
}
}
func locationManager(manager: CLLocationManager, didExitRegion region: CLRegion) {
print("EXITED REGION")
print("Identifier: \(region.identifier)")
if manager.location?.speed <= 3.5 {
self.updateLongAndLat(manager.location!, completion: { (lat, long) in
if lat != nil && long != nil {
let center = CLLocationCoordinate2D(latitude: lat!, longitude: long!)
let monitoredRegion = CLCircularRegion(center: center, radius: 10.0, identifier: "UserRegion")
self.locationManager.startMonitoringForRegion(monitoredRegion)
}
})
}
}
区域监控不依赖GPS。它是小区 tower/wifi 接入点三角测量。您不应期望水平精度优于 65m。试图用 65 米精度的仪器检测 10 米的运动根本行不通。
我不知道iOS在被要求监视半径小于100m的区域时做了什么。充其量它只是将半径增加到 100。在这种情况下,您的应用程序仍然可以运行,但可能不是预期的方式。
要从评论中回答您的问题,恐怕 Apple 没有提供对其核心定位技术的深入见解。这就是开发人员之间存在很多困惑的原因,因为似乎没有任何东西能按预期工作。对于初学者来说,核心位置 API 旨在实施最佳实践以最大程度地减少电池消耗。
如果您想使用小于 ~300 米(是的,三百米)的定位服务,则必须使用 GPS。地理围栏无法跟上不断行走的用户的步伐。但是在后台持续使用 GPS 运行 是不对的,因为你会很快耗尽电池,你的应用程序很快就会被用户 phone 驱逐。
地理围栏不需要 GPS,但会很乐意使用可用的 GPS 数据(即使其他应用程序请求了 GPS 更新)。 GPS 辅助地理围栏的工作非常精确,但我看不出有什么好的理由同时使用这两种服务,因为只需将位置管理器过滤器设置为正确的距离就更简单了。