【问题标题】:How to monitor more than 20 regions?如何监控20多个区域?
【发布时间】:2017-12-10 07:31:44
【问题描述】:

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

【问题讨论】:

    标签: ios swift monitoring region


    【解决方案1】:

    从您的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: $0.0)
        }
    
    }
    

    为了避免didSet被调用太多次,我建议你适当地设置distanceFilter(不要太大,这样你会太晚捕捉到区域的回调,也不要太小,这样你就不会有多余的代码跑步)。或者正如this answer 建议的那样,只需使用startMonitoringSignificantLocationChanges 更新您的currentLocation

    【讨论】:

    • 我在哪里放这个: var currentLocation : CLLocation?{ didSet{ evaluateClosestRegions() } }
    • @andre 你应该在采用cllocationmanagerdelegate 协议的类上创建一个属性。基本上与您获得didUpdateLocation回调的课程相同。
    • 我这样做了,但是函数 evaluateClosestRegions 永远不会被调用
    • @andre 你在你的didUpdatelocations 中设置currentLocation 吗?在里面做类似guard let location = locations.last else { return } currentLocation = location的事情。但老实说,我认为您首先需要做一些更基本的事情。你的问题太基础了。尝试多玩一下 coreLocation,看一些 Youtube 视频
    • 我看了一些核心定位的基础知识,现在它可以工作了。非常感谢
    【解决方案2】:

    没有办法使用 Apples API 监控超过 20 个区域。

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

    无论何时进入/离开一个区域:

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

    如果结果不令人满意,您可能还需要监控重大的位置变化,以便有机会每隔约 500 米更新一次监控区域,同时不会消耗太多电池。

    【讨论】:

    • 如何定义最近的区域并开始监控它们
    • 你有输入区域的位置(坐标)。您要监控的区域也有一个坐标。按 enterRegionsCoordinate.distanceTo(currentyChecktRegionsCoordinate) 对它们进行排序。如果这没有帮助,请发布一个新问题,说明您的实际问题、您尝试过的内容以及实际问题是什么。
    • @andre,如果这对您有帮助,您应该将其标记为您的答案。
    【解决方案3】:

    短而干净的解决方案:

    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 {
            ...
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-02
      • 2015-06-21
      • 1970-01-01
      • 2014-10-12
      • 2013-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多