如何监控20多个地区?

时间:2017-07-06 10:29:43

标签: ios swift monitoring region

我正在开发一个66个注释的应用程序。这些注释是区域的中心,每当用户进入区域时,都会显示通知,但仅适用于其中的20个,因为区域监控的数量有限。我的问题是我不知道如何监控20多个地区。有人可以帮忙吗?

3 个答案:

答案 0 :(得分:3)

使用Apples API无法监控20多个地区。

您必须将有效监控的区域更新到最近的20个区域。

每当您进入/离开某个地区时:

  • 检查输入的位置
  • 停止监控所有地区
  • 开始监控最近的19个区域(到输入位置的距离)加上输入的区域。

如果结果不满意,您可能还希望监控重要的位置变化,以便每隔500米更新受监控区域,同时不会耗尽太多电池。

答案 1 :(得分:2)

currentLocation

设置didUpdateLocations
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: $0.0)
    }

}

为了避免didSet被调用太多次,我建议你适当地设置distanceFilter(不要太大,这样你就会太晚捕捉该地区的回调,而不是太小,所以您没有运行冗余代码)。或者如this answer所示,只需使用startMonitoringSignificantLocationChanges更新currentLocation

即可

答案 2 :(得分:0)

简短的解决方案:

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: $0)
    }

    locations.sort {
        distance(from: $0) < distance(from: $1)
    }

    locations.prefix(20).forEach {
        ...
    }
}