如何监控20多个区域?
How to monitor more than 20 regions?
我正在开发一个有 66 个注释的应用程序。这些注释是区域的中心,每当用户进入一个区域时,都会出现一条通知,但这只适用于前 20 个区域,因为监视 regoins 的数量有限。我的问题是我不知道如何监控超过 20 个区域。有人可以帮忙吗?
无法使用 Apples 监控超过 20 个区域 API。
您必须将主动监控的区域更新为最近的 20 个区域。
每当你 enter/leave 一个地区:
- 检查输入的位置
- 停止监控所有区域
- 开始监控最近的 19 个区域(到输入位置的距离)加上输入的区域。
如果结果不令人满意,您可能还想监控重要的位置变化,以便有机会每 ~500 米更新一次监控区域,同时不会耗尽太多电池。
从您的 didUpdateLocations
设置 currentLocation
var currentLocation : CLLocation?{
didSet{
evaluateClosestRegions()
}
}
var allRegions : [CLRegion] = [] // Fill all your regions
现在计算并找到离您当前位置最近的区域,并只跟踪这些区域。
func evaluateClosestRegions() {
var allDistance : [Double] = []
//Calulate distance of each region's center to currentLocation
for region in allRegions{
let circularRegion = region as! CLCircularRegion
let distance = currentLocation!.distance(from: CLLocation(latitude: circularRegion.center.latitude, longitude: circularRegion.center.longitude))
allDistance.append(distance)
}
// a Array of Tuples
let distanceOfEachRegionToCurrentLocation = zip(allRegions, allDistance)
//sort and get 20 closest
let twentyNearbyRegions = distanceOfEachRegionToCurrentLocation
.sorted{ tuple1, tuple2 in return tuple1.1 < tuple2.1 }
.prefix(20)
// Remove all regions you were tracking before
for region in locationManager.monitoredRegions{
locationManager.stopMonitoring(for: region)
}
twentyNearbyRegions.forEach{
locationManager.startMonitoring(for: [=11=].0)
}
}
为了避免 didSet
被调用太多次,我建议您适当地设置 distanceFilter
(不要太大,否则您会太晚捕捉到该区域的回调,也不要太小,以至于您不会有冗余代码 运行)。或者按照 this answer 的建议,只需使用 startMonitoringSignificantLocationChanges
来更新您的 currentLocation
简洁明了的解决方案:
private var locations = [CLLocation]()
private var currentLocation: CLLocation? {
didSet {
evaluateClosestRegions()
}
}
private func distance(from location: CLLocation) -> Double {
return currentLocation.distance(from: location))
}
private func evaluateClosestRegions() {
locationManager.monitoredRegions.forEach {
locationManager.stopMonitoring(for: [=10=])
}
locations.sort {
distance(from: [=10=]) < distance(from: )
}
locations.prefix(20).forEach {
...
}
}
我正在开发一个有 66 个注释的应用程序。这些注释是区域的中心,每当用户进入一个区域时,都会出现一条通知,但这只适用于前 20 个区域,因为监视 regoins 的数量有限。我的问题是我不知道如何监控超过 20 个区域。有人可以帮忙吗?
无法使用 Apples 监控超过 20 个区域 API。
您必须将主动监控的区域更新为最近的 20 个区域。
每当你 enter/leave 一个地区:
- 检查输入的位置
- 停止监控所有区域
- 开始监控最近的 19 个区域(到输入位置的距离)加上输入的区域。
如果结果不令人满意,您可能还想监控重要的位置变化,以便有机会每 ~500 米更新一次监控区域,同时不会耗尽太多电池。
从您的 didUpdateLocations
currentLocation
var currentLocation : CLLocation?{
didSet{
evaluateClosestRegions()
}
}
var allRegions : [CLRegion] = [] // Fill all your regions
现在计算并找到离您当前位置最近的区域,并只跟踪这些区域。
func evaluateClosestRegions() {
var allDistance : [Double] = []
//Calulate distance of each region's center to currentLocation
for region in allRegions{
let circularRegion = region as! CLCircularRegion
let distance = currentLocation!.distance(from: CLLocation(latitude: circularRegion.center.latitude, longitude: circularRegion.center.longitude))
allDistance.append(distance)
}
// a Array of Tuples
let distanceOfEachRegionToCurrentLocation = zip(allRegions, allDistance)
//sort and get 20 closest
let twentyNearbyRegions = distanceOfEachRegionToCurrentLocation
.sorted{ tuple1, tuple2 in return tuple1.1 < tuple2.1 }
.prefix(20)
// Remove all regions you were tracking before
for region in locationManager.monitoredRegions{
locationManager.stopMonitoring(for: region)
}
twentyNearbyRegions.forEach{
locationManager.startMonitoring(for: [=11=].0)
}
}
为了避免 didSet
被调用太多次,我建议您适当地设置 distanceFilter
(不要太大,否则您会太晚捕捉到该区域的回调,也不要太小,以至于您不会有冗余代码 运行)。或者按照 this answer 的建议,只需使用 startMonitoringSignificantLocationChanges
来更新您的 currentLocation
简洁明了的解决方案:
private var locations = [CLLocation]()
private var currentLocation: CLLocation? {
didSet {
evaluateClosestRegions()
}
}
private func distance(from location: CLLocation) -> Double {
return currentLocation.distance(from: location))
}
private func evaluateClosestRegions() {
locationManager.monitoredRegions.forEach {
locationManager.stopMonitoring(for: [=10=])
}
locations.sort {
distance(from: [=10=]) < distance(from: )
}
locations.prefix(20).forEach {
...
}
}